[ASTERIXDB-2343][FUN] Implement to_array(), to_atomic(), to_object() - user model changes: yes - storage format changes: no - interface changes: no
Details: - Implement to_array(), to_atomic(), to_object() functions - Add function aliases: to_bool, to_str Change-Id: I6391a060ecd86cd397dd0a59f4930c4c55216d3b Reviewed-on: https://asterix-gerrit.ics.uci.edu/2539 Reviewed-by: Till Westmann <ti...@apache.org> Tested-by: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Contrib: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Integration-Tests: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/09182295 Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/09182295 Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/09182295 Branch: refs/heads/release-0.9.4-pre-rc Commit: 09182295dc03f92a5becd7dd2da93c0838907c3b Parents: cba9ec7 Author: Dmitry Lychagin <dmitry.lycha...@couchbase.com> Authored: Thu Mar 29 15:31:31 2018 -0700 Committer: Till Westmann <ti...@apache.org> Committed: Fri Mar 30 00:17:25 2018 -0700 ---------------------------------------------------------------------- .../optimizer/rules/ConstantFoldingRule.java | 3 +- .../types/to_array/to_array.1.query.sqlpp | 33 ++++ .../types/to_atomic/to_atomic.1.ddl.sqlpp | 30 +++ .../types/to_atomic/to_atomic.2.update.sqlpp | 32 +++ .../types/to_atomic/to_atomic.3.query.sqlpp | 32 +++ .../types/to_atomic/to_atomic.4.query.sqlpp | 24 +++ .../types/to_object/to_object.1.query.sqlpp | 33 ++++ .../to_string_01/to_string_01.1.query.sqlpp | 2 +- .../results/types/to_array/to_array.1.adm | 1 + .../results/types/to_atomic/to_atomic.3.adm | 1 + .../results/types/to_atomic/to_atomic.4.adm | 8 + .../results/types/to_object/to_object.1.adm | 1 + .../resources/runtimets/testsuite_sqlpp.xml | 43 ++-- .../src/main/markdown/builtins/11_type.md | 96 ++++++++- .../lang/common/util/CommonFunctionMapUtil.java | 11 +- .../asterix/om/functions/BuiltinFunctions.java | 23 ++- .../typecomputer/impl/ToArrayTypeComputer.java | 47 +++++ .../typecomputer/impl/ToObjectTypeComputer.java | 41 ++++ .../evaluators/functions/ToArrayDescriptor.java | 117 +++++++++++ .../functions/ToAtomicDescriptor.java | 194 +++++++++++++++++++ .../functions/ToObjectDescriptor.java | 97 ++++++++++ .../runtime/functions/FunctionCollection.java | 14 +- .../runtime/functions/FunctionTypeInferers.java | 10 + 23 files changed, 860 insertions(+), 33 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java index 7e9328b..29a8e77 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/ConstantFoldingRule.java @@ -92,7 +92,8 @@ public class ConstantFoldingRule implements IAlgebraicRewriteRule { BuiltinFunctions.GET_RECORD_FIELDS, BuiltinFunctions.GET_RECORD_FIELD_VALUE, BuiltinFunctions.FIELD_ACCESS_NESTED, BuiltinFunctions.GET_ITEM, BuiltinFunctions.OPEN_RECORD_CONSTRUCTOR, BuiltinFunctions.FIELD_ACCESS_BY_INDEX, BuiltinFunctions.CAST_TYPE, BuiltinFunctions.META, - BuiltinFunctions.META_KEY, BuiltinFunctions.RECORD_CONCAT, BuiltinFunctions.RECORD_CONCAT_STRICT); + BuiltinFunctions.META_KEY, BuiltinFunctions.RECORD_CONCAT, BuiltinFunctions.RECORD_CONCAT_STRICT, + BuiltinFunctions.TO_ATOMIC, BuiltinFunctions.TO_ARRAY); /** * Throws exceptions in substituiteProducedVariable, setVarType, and one getVarType method. http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_array/to_array.1.query.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_array/to_array.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_array/to_array.1.query.sqlpp new file mode 100644 index 0000000..c0814b5 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_array/to_array.1.query.sqlpp @@ -0,0 +1,33 @@ +/* + * 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. + */ + +{ + "t1": [ toarray(missing) is missing, toarray(null) is null, is_array(to_array([])) ], + "t2": to_array([]), + "t3": to_array([1]), + "t4": to_array([1,2]), + "t5": to_array("hello"), + "t6": to_array({"a":1}), + "t7": to_array({{ 2 }}), + "t8": ( + from range(1,4) t + select value to_array(t) + order by t + ) +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.1.ddl.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.1.ddl.sqlpp new file mode 100644 index 0000000..c156646 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.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 test if exists; +create dataverse test; + +use test; + +create type test.T1 as +{ + id : bigint +}; + +create dataset t1(T1) primary key id; http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.2.update.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.2.update.sqlpp new file mode 100644 index 0000000..2397ffb --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.2.update.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 test; + +insert into t1 select value t +from [ + { "id": 1, "v": 2 }, + { "id": 2, "v": "hello" }, + { "id": 3, "v": [[[2]]] }, + { "id": 4, "v": [[[2, 3]]] }, + { "id": 5, "v": {"a": 2} }, + { "id": 6, "v": {"a": 2, "b": 3} }, + { "id": 7, "v": {"a":{"b":{"c":{"d":2}}}} }, + { "id": 8, "v": {"a":[{"b":[{"c":[2]}]}]} } +] t http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.3.query.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.3.query.sqlpp new file mode 100644 index 0000000..07303d9 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.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. + */ + +{ + "t1": [ toatomic(missing) is missing, toatom(null) is null ], + "t2": [ to_atomic(1), to_atomic(true), to_atomic("hello") ], + "t3": [ to_atomic([]), to_atomic([2]), to_atomic([2,3]), to_atomic([[[[4]]]]) ], + "t4": [ to_atomic({{}}), to_atomic({{2}}), to_atomic({{2,3}}), to_atomic({{{{{{{{4}}}}}}}}) ], + "t5": [ to_atomic({}), to_atomic({"a":2}), to_atomic({"a":2, "b":3}), to_atomic({"a":{"b":{"c":{"d":4}}}}) ], + "t6": [ to_atomic([{"a":1}]), to_atomic([{"a":1, "b":2}]), to_atomic({"a":[{"b":[{"c":[2]}]}]}) ], + "t7": ( + from range(1,4) t + select to_atomic(t) v1, to_atomic([t]) v2, to_atomic({"a": t}) v3, to_atomic([[{"a":[t]}]]) v4 + order by t + ) +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.4.query.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.4.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.4.query.sqlpp new file mode 100644 index 0000000..95fb2cb --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_atomic/to_atomic.4.query.sqlpp @@ -0,0 +1,24 @@ +/* + * 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 test; + +select value [t.id, to_atomic(t.v) ] +from t1 t +order by t.id \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_object/to_object.1.query.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_object/to_object.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_object/to_object.1.query.sqlpp new file mode 100644 index 0000000..e7c04f7 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_object/to_object.1.query.sqlpp @@ -0,0 +1,33 @@ +/* + * 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. + */ + +{ + "t1": [ toobject(missing) is missing, toobj(null) is null ], + "t2": is_object(to_object({})), + "t3": to_object({}), + "t4": to_object({"a":1}), + "t5": to_object({"a":1, "b":2}), + "t6": ( + from [ + int8("1"), int16("2"), int32("3"), int64("4"), float("5"), double("6"), + "hello", [7], [ { "a": 1 } ] + ] t + select value to_object(t) + ) +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp index f759e16..52a39fc 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp @@ -18,7 +18,7 @@ */ { "t1": tostring(false), - "t2": to_string(true), + "t2": tostr(true), "t3": to_string(int8("8")), "t4": to_string(int16("16")), "t5": to_string(int32("32")), http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_array/to_array.1.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_array/to_array.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_array/to_array.1.adm new file mode 100644 index 0000000..5aeb739 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_array/to_array.1.adm @@ -0,0 +1 @@ +{ "t1": [ true, true, true ], "t2": [ ], "t3": [ 1 ], "t4": [ 1, 2 ], "t5": [ "hello" ], "t6": [ { "a": 1 } ], "t7": [ 2 ], "t8": [ [ 1 ], [ 2 ], [ 3 ], [ 4 ] ] } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.3.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.3.adm new file mode 100644 index 0000000..aec2ce7 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.3.adm @@ -0,0 +1 @@ +{ "t1": [ true, true ], "t2": [ 1, true, "hello" ], "t3": [ null, 2, null, 4 ], "t4": [ null, 2, null, 4 ], "t5": [ null, 2, null, 4 ], "t6": [ 1, null, 2 ], "t7": [ { "v1": 1, "v2": 1, "v3": 1, "v4": 1 }, { "v1": 2, "v2": 2, "v3": 2, "v4": 2 }, { "v1": 3, "v2": 3, "v3": 3, "v4": 3 }, { "v1": 4, "v2": 4, "v3": 4, "v4": 4 } ] } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.4.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.4.adm new file mode 100644 index 0000000..3f4c517 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_atomic/to_atomic.4.adm @@ -0,0 +1,8 @@ +[ 1, 2 ] +[ 2, "hello" ] +[ 3, 2 ] +[ 4, null ] +[ 5, 2 ] +[ 6, null ] +[ 7, 2 ] +[ 8, 2 ] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_object/to_object.1.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_object/to_object.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_object/to_object.1.adm new file mode 100644 index 0000000..ceb84c2 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_object/to_object.1.adm @@ -0,0 +1 @@ +{ "t1": [ true, true ], "t2": true, "t3": { }, "t4": { "a": 1 }, "t5": { "a": 1, "b": 2 }, "t6": [ { }, { }, { }, { }, { }, { }, { }, { }, { } ] } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml ---------------------------------------------------------------------- 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 dd2b626..1b49358 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml @@ -9229,6 +9229,16 @@ </compilation-unit> </test-case> <test-case FilePath="types"> + <compilation-unit name="to_array"> + <output-dir compare="Text">to_array</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="types"> + <compilation-unit name="to_atomic"> + <output-dir compare="Text">to_atomic</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="types"> <compilation-unit name="to_boolean_01"> <output-dir compare="Text">to_boolean_01</output-dir> </compilation-unit> @@ -9240,14 +9250,14 @@ </compilation-unit> </test-case> <test-case FilePath="types"> - <compilation-unit name="to_string_01"> - <output-dir compare="Text">to_string_01</output-dir> + <compilation-unit name="to_bigint_01"> + <output-dir compare="Text">to_bigint_01</output-dir> </compilation-unit> </test-case> <test-case FilePath="types"> - <compilation-unit name="to_string_02"> - <output-dir compare="Text">to_string_02</output-dir> - <expected-error>ASX0004: Unsupported type</expected-error> + <compilation-unit name="to_bigint_02"> + <output-dir compare="Text">to_bigint_02</output-dir> + <expected-error>ASX0002: Type mismatch</expected-error> </compilation-unit> </test-case> <test-case FilePath="types"> @@ -9262,25 +9272,30 @@ </compilation-unit> </test-case> <test-case FilePath="types"> - <compilation-unit name="to_bigint_01"> - <output-dir compare="Text">to_bigint_01</output-dir> + <compilation-unit name="to_number_01"> + <output-dir compare="Text">to_number_01</output-dir> </compilation-unit> </test-case> <test-case FilePath="types"> - <compilation-unit name="to_bigint_02"> - <output-dir compare="Text">to_bigint_02</output-dir> + <compilation-unit name="to_number_02"> + <output-dir compare="Text">to_number_02</output-dir> <expected-error>ASX0002: Type mismatch</expected-error> </compilation-unit> </test-case> <test-case FilePath="types"> - <compilation-unit name="to_number_01"> - <output-dir compare="Text">to_number_01</output-dir> + <compilation-unit name="to_object"> + <output-dir compare="Text">to_object</output-dir> </compilation-unit> </test-case> <test-case FilePath="types"> - <compilation-unit name="to_number_02"> - <output-dir compare="Text">to_number_02</output-dir> - <expected-error>ASX0002: Type mismatch</expected-error> + <compilation-unit name="to_string_01"> + <output-dir compare="Text">to_string_01</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="types"> + <compilation-unit name="to_string_02"> + <output-dir compare="Text">to_string_02</output-dir> + <expected-error>ASX0004: Unsupported type</expected-error> </compilation-unit> </test-case> </test-group> http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md index f972735..578508f 100644 --- a/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md +++ b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md @@ -293,6 +293,67 @@ The function has an alias `isunknown`. +### to_array ### + * Syntax: + + to_array(expr) + + * Converts input value to an `array` value + * Arguments: + * `expr` : an expression + * Return Value: + * if the argument is `missing` then `missing` is returned + * if the argument is `null` then `null` is returned + * if the argument is of `array` type then it is returned as is + * if the argument is of `multiset` type then it is returned as an `array` with elements in an undefined order + * otherwise an `array` containing the input expression as its single item is returned + + * Example: + + { + "v1": to_array("asterix"), + "v2": to_array(["asterix"]), + }; + + * The expected result is: + + { "v1": ["asterix"], "v2": ["asterix"] } + + The function has an alias `toarray`. + +### to_atomic ### + * Syntax: + + to_atomic(expr) + + * Converts input value to a [primitive](../datamodel.html#PrimitiveTypes) value + * Arguments: + * `expr` : an expression + * Return Value: + * if the argument is `missing` then `missing` is returned + * if the argument is `null` then `null` is returned + * if the argument is of primitive type then it is returned as is + * if the argument is of `array` or `multiset` type and has only one element then the result of invoking + to_atomic() on that element is returned + * if the argument is of `object` type and has only one field then the result of invoking to_atomic() on the + value of that field is returned + * otherwise `null` is returned + + * Example: + + { + "v1": to_atomic("asterix"), + "v2": to_atomic(["asterix"]), + "v3": to_atomic([0, 1]), + "v4": to_atomic({"value": "asterix"}), + "v5": to_number({"x": 1, "y": 2}) + }; + + * The expected result is: + + { "v1": "asterix", "v2": "asterix", "v3": null, "v4": "asterix", "v5": null } + + The function has two aliases, `toatomic` or `toatom`. ### to_boolean ### * Syntax: @@ -325,8 +386,7 @@ { "v1": false, "v2": true, "v3": false, "v4": true } - The function has an alias `toboolean`. - + The function has two aliases, `toboolean` or `tobool`. ### to_bigint ### * Syntax: @@ -364,7 +424,6 @@ The function has an alias `tobigint`. - ### to_double ### * Syntax: @@ -432,7 +491,34 @@ { "v1": 0, "v2": 1, "v3": 10, "v4": 11.5, "v5": 12.5 } - The function has an alias `tonumber`. + The function has two aliases, `tonumber` or `tonum`. + +### to_object ### + * Syntax: + + to_object(expr) + + * Converts input value to an `object` value + * Arguments: + * `expr` : an expression + * Return Value: + * if the argument is `missing` then `missing` is returned + * if the argument is `null` then `null` is returned + * if the argument is of `object` type then it is returned as is + * otherwise an empty `object` is returned + + * Example: + + { + "v1": to_object({"value": "asterix"}), + "v2": to_object("asterix") + }; + + * The expected result is: + + { "v1": {"value": "asterix"}, "v2": {} } + + The function has two aliases, `toobject` or `toobj`. ### to_string ### * Syntax: @@ -465,4 +551,4 @@ { "v1": "false", "v2": "true", "v3": "10", "v4": "11.5", "v5": "asterix" } - The function has an alias `tostring`. + The function has two aliases, `tostring` or `tostr`. http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/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 3116521..3dffc00 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 @@ -69,12 +69,19 @@ public class CommonFunctionMapUtil { addFunctionMapping("ifinf", "if-inf"); // ifinf, internal: if-inf addFunctionMapping("ifnan", "if-nan"); // ifnan, internal: if-nan addFunctionMapping("ifnanorinf", "if-nan-or-inf"); // ifnanorinf, internal: if-nan-or-inf + addFunctionMapping("toarray", "to-array"); // toarray, internal: to-array + addFunctionMapping("toatomic", "to-atomic"); // toatomic, internal: to-atomic + addFunctionMapping("toatom", "to-atomic"); // toatom, internal: to-atomic addFunctionMapping("toboolean", "to-boolean"); // toboolean, internal: to-boolean - addFunctionMapping("tostring", "to-string"); // tostring, internal: to-string - addFunctionMapping("todouble", "to-double"); // todouble, internal: to-double + addFunctionMapping("tobool", "to-boolean"); // tobool, internal: to-boolean addFunctionMapping("tobigint", "to-bigint"); // tobigint, internal: to-bigint + addFunctionMapping("todouble", "to-double"); // todouble, internal: to-double + addFunctionMapping("tostring", "to-string"); // tostring, internal: to-string + addFunctionMapping("tostr", "to-string"); // tostr, internal: to-string addFunctionMapping("tonumber", "to-number"); // tonumber, internal: to-number addFunctionMapping("tonum", "to-number"); // tonum, internal: to-number + addFunctionMapping("toobject", "to-object"); // toobject, internal: to-object + addFunctionMapping("toobj", "to-object"); // toobj, internal: to-object // Object functions // record-merge, internal: object-merge http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java ---------------------------------------------------------------------- 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 6b86a26..8cd18fc 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 @@ -106,9 +106,11 @@ import org.apache.asterix.om.typecomputer.impl.StringToStringListTypeComputer; import org.apache.asterix.om.typecomputer.impl.SubsetCollectionTypeComputer; import org.apache.asterix.om.typecomputer.impl.SubstringTypeComputer; import org.apache.asterix.om.typecomputer.impl.SwitchCaseComputer; +import org.apache.asterix.om.typecomputer.impl.ToArrayTypeComputer; import org.apache.asterix.om.typecomputer.impl.ToBigIntTypeComputer; import org.apache.asterix.om.typecomputer.impl.ToDoubleTypeComputer; import org.apache.asterix.om.typecomputer.impl.ToNumberTypeComputer; +import org.apache.asterix.om.typecomputer.impl.ToObjectTypeComputer; import org.apache.asterix.om.typecomputer.impl.UnaryBinaryInt64TypeComputer; import org.apache.asterix.om.typecomputer.impl.UnaryMinusTypeComputer; import org.apache.asterix.om.typecomputer.impl.UnaryStringInt64TypeComputer; @@ -874,16 +876,22 @@ public class BuiltinFunctions { public static final FunctionIdentifier IF_NAN_OR_INF = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "if-nan-or-inf", FunctionIdentifier.VARARGS); + public static final FunctionIdentifier TO_ATOMIC = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-atomic", 1); + public static final FunctionIdentifier TO_ARRAY = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-array", 1); + public static final FunctionIdentifier TO_BIGINT = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-bigint", 1); public static final FunctionIdentifier TO_BOOLEAN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-boolean", 1); - public static final FunctionIdentifier TO_STRING = - new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-string", 1); public static final FunctionIdentifier TO_DOUBLE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-double", 1); - public static final FunctionIdentifier TO_BIGINT = - new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-bigint", 1); public static final FunctionIdentifier TO_NUMBER = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-number", 1); + public static final FunctionIdentifier TO_OBJECT = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-object", 1); + public static final FunctionIdentifier TO_STRING = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-string", 1); public static final FunctionIdentifier EXTERNAL_LOOKUP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "external-lookup", FunctionIdentifier.VARARGS); @@ -1070,11 +1078,14 @@ public class BuiltinFunctions { addFunction(RANGE, AInt64TypeComputer.INSTANCE, true); addFunction(RECTANGLE_CONSTRUCTOR, ARectangleTypeComputer.INSTANCE, true); + addFunction(TO_ATOMIC, AnyTypeComputer.INSTANCE, true); + addFunction(TO_ARRAY, ToArrayTypeComputer.INSTANCE, true); + addFunction(TO_BIGINT, ToBigIntTypeComputer.INSTANCE, true); addFunction(TO_BOOLEAN, ABooleanTypeComputer.INSTANCE, true); - addFunction(TO_STRING, AStringTypeComputer.INSTANCE, true); addFunction(TO_DOUBLE, ToDoubleTypeComputer.INSTANCE, true); - addFunction(TO_BIGINT, ToBigIntTypeComputer.INSTANCE, true); addFunction(TO_NUMBER, ToNumberTypeComputer.INSTANCE, true); + addFunction(TO_OBJECT, ToObjectTypeComputer.INSTANCE, true); + addFunction(TO_STRING, AStringTypeComputer.INSTANCE, true); // Aggregate Functions addFunction(MAX, MinMaxAggTypeComputer.INSTANCE, true); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToArrayTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToArrayTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToArrayTypeComputer.java new file mode 100644 index 0000000..e33284f --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToArrayTypeComputer.java @@ -0,0 +1,47 @@ +/* + * 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.AOrderedListType; +import org.apache.asterix.om.types.AUnorderedListType; +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 ToArrayTypeComputer extends AbstractResultTypeComputer { + public static final ToArrayTypeComputer INSTANCE = new ToArrayTypeComputer(); + + private ToArrayTypeComputer() { + } + + @Override + protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { + IAType argType = strippedInputTypes[0]; + switch (argType.getTypeTag()) { + case ARRAY: + return argType; + case MULTISET: + return new AOrderedListType(((AUnorderedListType) argType).getItemType(), null); + default: + return new AOrderedListType(argType, null); + } + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToObjectTypeComputer.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToObjectTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToObjectTypeComputer.java new file mode 100644 index 0000000..116f7ac --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ToObjectTypeComputer.java @@ -0,0 +1,41 @@ +/* + * 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.ATypeTag; +import org.apache.asterix.om.types.IAType; +import org.apache.asterix.om.utils.RecordUtil; +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; + +public class ToObjectTypeComputer extends AbstractResultTypeComputer { + public static final ToObjectTypeComputer INSTANCE = new ToObjectTypeComputer(); + + private ToObjectTypeComputer() { + } + + @Override + protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { + IAType strippedInputType = strippedInputTypes[0]; + return strippedInputType.getTypeTag() == ATypeTag.OBJECT ? strippedInputType + : RecordUtil.FULLY_OPEN_RECORD_TYPE; + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToArrayDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToArrayDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToArrayDescriptor.java new file mode 100644 index 0000000..9764aed --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToArrayDescriptor.java @@ -0,0 +1,117 @@ +/* + * 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.DataOutput; +import java.io.IOException; + +import org.apache.asterix.builders.OrderedListBuilder; +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.typecomputer.impl.TypeComputeUtils; +import org.apache.asterix.om.types.AOrderedListType; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.asterix.om.types.IAType; +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; +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 ToArrayDescriptor extends AbstractScalarFunctionDynamicDescriptor { + public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { + @Override + public IFunctionDescriptor createFunctionDescriptor() { + return new ToArrayDescriptor(); + } + + @Override + public IFunctionTypeInferer createFunctionTypeInferer() { + return FunctionTypeInferers.SET_EXPRESSION_TYPE; + } + }; + + private static final long serialVersionUID = 1L; + private AOrderedListType oltype; + + @Override + public void setImmutableStates(Object... states) { + oltype = TypeComputeUtils.extractOrderedListType((IAType) states[0]); + } + + @Override + public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) { + return new IScalarEvaluatorFactory() { + private static final long serialVersionUID = 1L; + + @Override + public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException { + + return new IScalarEvaluator() { + + private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx); + private final IPointable arg0 = new VoidPointable(); + private final OrderedListBuilder listBuilder = new OrderedListBuilder(); + private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); + private final DataOutput out = resultStorage.getDataOutput(); + + @Override + public void evaluate(IFrameTupleReference tuple, IPointable resultPointable) + throws HyracksDataException { + eval0.evaluate(tuple, arg0); + byte[] data = arg0.getByteArray(); + int offset = arg0.getStartOffset(); + if (data[offset] == ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG) { + resultPointable.set(arg0); + } else if (data[offset] == ATypeTag.SERIALIZED_UNORDEREDLIST_TYPE_TAG) { + try { + resultStorage.reset(); + out.writeByte(ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG); + out.write(data, offset + 1, arg0.getLength() - 1); + resultPointable.set(resultStorage); + } catch (IOException e) { + throw HyracksDataException.create(e); + } + } else { + resultStorage.reset(); + listBuilder.reset(oltype); + listBuilder.addItem(arg0); + listBuilder.write(out, true); + resultPointable.set(resultStorage); + } + } + }; + } + }; + } + + @Override + public FunctionIdentifier getIdentifier() { + return BuiltinFunctions.TO_ARRAY; + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToAtomicDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToAtomicDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToAtomicDescriptor.java new file mode 100644 index 0000000..16554b5 --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToAtomicDescriptor.java @@ -0,0 +1,194 @@ +/* + * 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.util.List; + +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.pointables.AListVisitablePointable; +import org.apache.asterix.om.pointables.ARecordVisitablePointable; +import org.apache.asterix.om.pointables.PointableAllocator; +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.AUnionType; +import org.apache.asterix.om.types.AUnorderedListType; +import org.apache.asterix.om.types.BuiltinType; +import org.apache.asterix.om.types.IAType; +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; +import org.apache.hyracks.data.std.api.IPointable; +import org.apache.hyracks.data.std.api.IValueReference; +import org.apache.hyracks.data.std.primitive.VoidPointable; +import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference; + +public class ToAtomicDescriptor extends AbstractScalarFunctionDynamicDescriptor { + public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { + @Override + public IFunctionDescriptor createFunctionDescriptor() { + return new ToAtomicDescriptor(); + } + + @Override + public IFunctionTypeInferer createFunctionTypeInferer() { + return FunctionTypeInferers.SET_ARGUMENT_TYPE; + } + }; + + private static final long serialVersionUID = 1L; + private IAType argType; + + @Override + public void setImmutableStates(Object... states) { + argType = (IAType) states[0]; + } + + @Override + public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) { + return new IScalarEvaluatorFactory() { + private static final long serialVersionUID = 1L; + + @Override + public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException { + + return new IScalarEvaluator() { + + private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx); + private final IPointable arg = new VoidPointable(); + + private final PointableAllocator pAlloc = new PointableAllocator(); + + @Override + public void evaluate(IFrameTupleReference tuple, IPointable resultPointable) + throws HyracksDataException { + eval0.evaluate(tuple, arg); + + IValueReference itemPtr = arg; + IAType itemTypeInferred = argType; + + for (;;) { + byte[] itemData = itemPtr.getByteArray(); + int itemOffset = itemPtr.getStartOffset(); + ATypeTag typeTag = ATypeTag.VALUE_TYPE_MAPPING[itemData[itemOffset]]; + switch (typeTag) { + case ARRAY: + case MULTISET: + AListVisitablePointable listPointable = + (AListVisitablePointable) allocatePointable(itemTypeInferred, typeTag); + listPointable.set(itemPtr); + List<IVisitablePointable> listItems = listPointable.getItems(); + if (listItems.size() != 1) { + PointableHelper.setNull(resultPointable); + return; + } + itemPtr = listItems.get(0); + itemTypeInferred = getListItemType(itemTypeInferred); + break; + case OBJECT: + ARecordType recType = asRecordType(itemTypeInferred); + ARecordVisitablePointable recPointable = + (ARecordVisitablePointable) allocatePointable(itemTypeInferred, typeTag); + recPointable.set(itemPtr); + List<IVisitablePointable> recValues = recPointable.getFieldValues(); + if (recValues.size() != 1) { + PointableHelper.setNull(resultPointable); + return; + } + itemPtr = recValues.get(0); + itemTypeInferred = recType.getFieldTypes().length == 1 ? recType.getFieldTypes()[0] + : BuiltinType.ANY; + break; + default: + resultPointable.set(itemPtr); + return; + } + } + } + + private IVisitablePointable allocatePointable(IAType inferredType, ATypeTag actualTypeTag) { + if (inferredType.equals(BuiltinType.ANY)) { + return allocatePointableForAny(actualTypeTag); + } + return pAlloc.allocateFieldValue(inferredType); + } + + private IVisitablePointable allocatePointableForAny(ATypeTag typeTag) { + switch (typeTag) { + case OBJECT: + return pAlloc.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE); + case ARRAY: + return pAlloc.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE); + case MULTISET: + return pAlloc.allocateFieldValue(DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE); + default: + return pAlloc.allocateFieldValue(null); + } + } + + private ARecordType asRecordType(IAType inferredType) { + switch (inferredType.getTypeTag()) { + case OBJECT: + return (ARecordType) inferredType; + case UNION: + IAType innerType = ((AUnionType) inferredType).getActualType(); + if (innerType.getTypeTag() == ATypeTag.OBJECT) { + return (ARecordType) innerType; + } + } + return DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE; + } + + private IAType getListItemType(IAType inferredType) { + switch (inferredType.getTypeTag()) { + case ARRAY: + return ((AOrderedListType) inferredType).getItemType(); + case MULTISET: + return ((AUnorderedListType) inferredType).getItemType(); + case UNION: + IAType innerType = ((AUnionType) inferredType).getActualType(); + switch (innerType.getTypeTag()) { + case ARRAY: + return ((AOrderedListType) innerType).getItemType(); + case MULTISET: + return ((AUnorderedListType) innerType).getItemType(); + } + } + return BuiltinType.ANY; + } + }; + } + }; + } + + @Override + public FunctionIdentifier getIdentifier() { + return BuiltinFunctions.TO_ATOMIC; + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToObjectDescriptor.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToObjectDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToObjectDescriptor.java new file mode 100644 index 0000000..82dbd95 --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToObjectDescriptor.java @@ -0,0 +1,97 @@ +/* + * 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.DataOutput; + +import org.apache.asterix.builders.RecordBuilder; +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.types.ATypeTag; +import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; +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 ToObjectDescriptor extends AbstractScalarFunctionDynamicDescriptor { + public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { + @Override + public IFunctionDescriptor createFunctionDescriptor() { + return new ToObjectDescriptor(); + } + }; + + @Override + public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) { + return new IScalarEvaluatorFactory() { + private static final long serialVersionUID = 1L; + + @Override + public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException { + + return new IScalarEvaluator() { + + private final IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx); + private final IPointable arg0 = new VoidPointable(); + private final RecordBuilder recordBuilder = new RecordBuilder(); + private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); + private final DataOutput out = resultStorage.getDataOutput(); + private boolean wroteEmpty; + + @Override + public void evaluate(IFrameTupleReference tuple, IPointable resultPointable) + throws HyracksDataException { + eval0.evaluate(tuple, arg0); + byte[] data = arg0.getByteArray(); + int offset = arg0.getStartOffset(); + if (data[offset] == ATypeTag.SERIALIZED_RECORD_TYPE_TAG) { + resultPointable.set(arg0); + } else { + writeEmpty(); + resultPointable.set(resultStorage); + } + } + + private void writeEmpty() throws HyracksDataException { + if (!wroteEmpty) { + resultStorage.reset(); + recordBuilder.reset(null); + recordBuilder.init(); + recordBuilder.write(out, true); + wroteEmpty = true; + } + } + }; + } + }; + } + + @Override + public FunctionIdentifier getIdentifier() { + return BuiltinFunctions.TO_OBJECT; + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java ---------------------------------------------------------------------- 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 6648ff2..b05dbed 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 @@ -241,10 +241,13 @@ import org.apache.asterix.runtime.evaluators.functions.SubstringAfterDescriptor; import org.apache.asterix.runtime.evaluators.functions.SubstringBeforeDescriptor; import org.apache.asterix.runtime.evaluators.functions.SubstringDescriptor; import org.apache.asterix.runtime.evaluators.functions.SwitchCaseDescriptor; +import org.apache.asterix.runtime.evaluators.functions.ToArrayDescriptor; +import org.apache.asterix.runtime.evaluators.functions.ToAtomicDescriptor; import org.apache.asterix.runtime.evaluators.functions.ToBigIntDescriptor; import org.apache.asterix.runtime.evaluators.functions.ToBooleanDescriptor; import org.apache.asterix.runtime.evaluators.functions.ToDoubleDescriptor; import org.apache.asterix.runtime.evaluators.functions.ToNumberDescriptor; +import org.apache.asterix.runtime.evaluators.functions.ToObjectDescriptor; import org.apache.asterix.runtime.evaluators.functions.ToStringDescriptor; import org.apache.asterix.runtime.evaluators.functions.UUIDDescriptor; import org.apache.asterix.runtime.evaluators.functions.binary.BinaryConcatDescriptor; @@ -689,17 +692,20 @@ public final class FunctionCollection implements IFunctionCollection { fc.addGenerated(DurationFromIntervalDescriptor.FACTORY); // Type functions. + fc.addGenerated(IsArrayDescriptor.FACTORY); fc.addGenerated(IsAtomicDescriptor.FACTORY); fc.addGenerated(IsBooleanDescriptor.FACTORY); fc.addGenerated(IsNumberDescriptor.FACTORY); - fc.addGenerated(IsStringDescriptor.FACTORY); - fc.addGenerated(IsArrayDescriptor.FACTORY); fc.addGenerated(IsObjectDescriptor.FACTORY); + fc.addGenerated(IsStringDescriptor.FACTORY); + fc.addGenerated(ToArrayDescriptor.FACTORY); + fc.addGenerated(ToAtomicDescriptor.FACTORY); + fc.addGenerated(ToBigIntDescriptor.FACTORY); fc.addGenerated(ToBooleanDescriptor.FACTORY); - fc.addGenerated(ToStringDescriptor.FACTORY); fc.addGenerated(ToDoubleDescriptor.FACTORY); - fc.addGenerated(ToBigIntDescriptor.FACTORY); fc.addGenerated(ToNumberDescriptor.FACTORY); + fc.addGenerated(ToObjectDescriptor.FACTORY); + fc.addGenerated(ToStringDescriptor.FACTORY); // Cast function fc.addGenerated(CastTypeDescriptor.FACTORY); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/09182295/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java index be041e5..e5a4301 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java @@ -69,6 +69,16 @@ public final class FunctionTypeInferers { } }; + public static final IFunctionTypeInferer SET_ARGUMENT_TYPE = new IFunctionTypeInferer() { + @Override + public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context, + CompilerProperties compilerProps) throws AlgebricksException { + AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr; + IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue()); + fd.setImmutableStates(TypeComputeUtils.getActualType(t)); + } + }; + public static final class CastTypeInferer implements IFunctionTypeInferer { @Override public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context,