[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 <tillw@apache.org>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
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 @@
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.
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
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;
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
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
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
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
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")),
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
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
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
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
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,28 +9250,6 @@
</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>
- </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-case FilePath="types">
- <compilation-unit name="to_double_01">
- <output-dir compare="Text">to_double_01</output-dir>
- </compilation-unit>
- </test-case>
- <test-case FilePath="types">
- <compilation-unit name="to_double_02">
- <output-dir compare="Text">to_double_02</output-dir>
- <expected-error>ASX0002: Type mismatch</expected-error>
- </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>
@@ -9273,6 +9261,17 @@
</compilation-unit>
</test-case>
<test-case FilePath="types">
+ <compilation-unit name="to_double_01">
+ <output-dir compare="Text">to_double_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="types">
+ <compilation-unit name="to_double_02">
+ <output-dir compare="Text">to_double_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>
@@ -9283,6 +9282,22 @@
<expected-error>ASX0002: Type mismatch</expected-error>
</compilation-unit>
</test-case>
+ <test-case FilePath="types">
+ <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_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>
<test-group name="materialization">
<test-case FilePath="materialization">
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`.
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 @@
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
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.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 static final FunctionIdentifier IF_NAN_OR_INF =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "if-nan-or-inf", FunctionIdentifier.VARARGS);
- 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_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_DOUBLE =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-double", 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 @@
addFunction(RANGE, AInt64TypeComputer.INSTANCE, true);
addFunction(RECTANGLE_CONSTRUCTOR, ARectangleTypeComputer.INSTANCE, true);
- addFunction(TO_BOOLEAN, ABooleanTypeComputer.INSTANCE, true);
- addFunction(TO_STRING, AStringTypeComputer.INSTANCE, true);
- addFunction(TO_DOUBLE, ToDoubleTypeComputer.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_DOUBLE, ToDoubleTypeComputer.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);
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);
+ }
+ }
+}
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;
+ }
+}
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;
+ }
+}
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;
+ }
+}
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;
+ }
+}
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.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 @@
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(ToBooleanDescriptor.FACTORY);
- fc.addGenerated(ToStringDescriptor.FACTORY);
- fc.addGenerated(ToDoubleDescriptor.FACTORY);
+ fc.addGenerated(IsStringDescriptor.FACTORY);
+ fc.addGenerated(ToArrayDescriptor.FACTORY);
+ fc.addGenerated(ToAtomicDescriptor.FACTORY);
fc.addGenerated(ToBigIntDescriptor.FACTORY);
+ fc.addGenerated(ToBooleanDescriptor.FACTORY);
+ fc.addGenerated(ToDoubleDescriptor.FACTORY);
fc.addGenerated(ToNumberDescriptor.FACTORY);
+ fc.addGenerated(ToObjectDescriptor.FACTORY);
+ fc.addGenerated(ToStringDescriptor.FACTORY);
// Cast function
fc.addGenerated(CastTypeDescriptor.FACTORY);
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 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,