[ASTERIXDB-1964][FUN] Add type conversion functions
- user model changes: yes
- storage format changes: no
- interface changes: no
Details:
- Added type conversion functions: to_boolean(), to_string(),
to_double(), to_bigint()
Change-Id: I7cf119d8a5dd172f4ce2402315fabf7db084559c
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1861
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Yingyi Bu <buyingyi@gmail.com>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
index f833692..92ca977 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
@@ -130,9 +130,12 @@
import org.apache.asterix.runtime.evaluators.constructors.AYearMonthDurationConstructorDescriptor;
import org.apache.asterix.runtime.evaluators.constructors.ClosedRecordConstructorDescriptor;
import org.apache.asterix.runtime.evaluators.constructors.OpenRecordConstructorDescriptor;
+import org.apache.asterix.runtime.evaluators.constructors.OrderedListConstructorDescriptor;
+import org.apache.asterix.runtime.evaluators.constructors.UnorderedListConstructorDescriptor;
import org.apache.asterix.runtime.evaluators.functions.AndDescriptor;
import org.apache.asterix.runtime.evaluators.functions.AnyCollectionMemberDescriptor;
import org.apache.asterix.runtime.evaluators.functions.CastTypeDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.CastTypeLaxDescriptor;
import org.apache.asterix.runtime.evaluators.functions.CheckUnknownDescriptor;
import org.apache.asterix.runtime.evaluators.functions.CodePointToStringDescriptor;
import org.apache.asterix.runtime.evaluators.functions.CountHashedGramTokensDescriptor;
@@ -160,7 +163,6 @@
import org.apache.asterix.runtime.evaluators.functions.IfMissingDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IfMissingOrNullDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IfNullDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.CastTypeLaxDescriptor;
import org.apache.asterix.runtime.evaluators.functions.InjectFailureDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IsArrayDescriptor;
import org.apache.asterix.runtime.evaluators.functions.IsBooleanDescriptor;
@@ -200,7 +202,6 @@
import org.apache.asterix.runtime.evaluators.functions.NumericTruncDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericUnaryMinusDescriptor;
import org.apache.asterix.runtime.evaluators.functions.OrDescriptor;
-import org.apache.asterix.runtime.evaluators.constructors.OrderedListConstructorDescriptor;
import org.apache.asterix.runtime.evaluators.functions.PrefixLenJaccardDescriptor;
import org.apache.asterix.runtime.evaluators.functions.SimilarityJaccardCheckDescriptor;
import org.apache.asterix.runtime.evaluators.functions.SimilarityJaccardDescriptor;
@@ -247,8 +248,11 @@
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.ToBigIntDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ToBooleanDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ToDoubleDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ToStringDescriptor;
import org.apache.asterix.runtime.evaluators.functions.UUIDDescriptor;
-import org.apache.asterix.runtime.evaluators.constructors.UnorderedListConstructorDescriptor;
import org.apache.asterix.runtime.evaluators.functions.WordTokensDescriptor;
import org.apache.asterix.runtime.evaluators.functions.binary.BinaryConcatDescriptor;
import org.apache.asterix.runtime.evaluators.functions.binary.BinaryLengthDescriptor;
@@ -693,6 +697,10 @@
functionsToInjectUnkownHandling.add(IsStringDescriptor.FACTORY);
functionsToInjectUnkownHandling.add(IsArrayDescriptor.FACTORY);
functionsToInjectUnkownHandling.add(IsObjectDescriptor.FACTORY);
+ functionsToInjectUnkownHandling.add(ToBooleanDescriptor.FACTORY);
+ functionsToInjectUnkownHandling.add(ToStringDescriptor.FACTORY);
+ functionsToInjectUnkownHandling.add(ToDoubleDescriptor.FACTORY);
+ functionsToInjectUnkownHandling.add(ToBigIntDescriptor.FACTORY);
// Cast function
functionsToInjectUnkownHandling.add(CastTypeDescriptor.FACTORY);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_bigint_01/to_bigint_01.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_bigint_01/to_bigint_01.1.query.aql
new file mode 100644
index 0000000..837cb86
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_bigint_01/to_bigint_01.1.query.aql
@@ -0,0 +1,35 @@
+/*
+ * 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": tobigint(false),
+ "t2": to-bigint(true),
+ "t3": to_bigint(int8("8")),
+ "t4": to_bigint(int16("16")),
+ "t5": to_bigint(int32("32")),
+ "t6": to_bigint(int64("64")),
+ "t7": to_bigint(float("1e100")),
+ "t8": to_bigint(double("1e1000")),
+ "t9": to_bigint("512"),
+ "t10": is_null(to_bigint("foo")),
+ "t11": is_null(to_bigint([])),
+ "t12": is_null(to_bigint({{}})),
+ "t13": is_null(to_bigint({})),
+ "t14": is_null(to_bigint(null)),
+ "t15": is_missing(to_bigint(missing))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_bigint_02/to_bigint_02.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_bigint_02/to_bigint_02.1.query.aql
new file mode 100644
index 0000000..13f482f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_bigint_02/to_bigint_02.1.query.aql
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+{
+ "t": to_bigint(date("2017-06-30"))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_boolean_01/to_boolean_01.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_boolean_01/to_boolean_01.1.query.aql
new file mode 100644
index 0000000..3e52730
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_boolean_01/to_boolean_01.1.query.aql
@@ -0,0 +1,61 @@
+/*
+ * 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": toboolean(false),
+ "t2": to-boolean(true),
+
+ "t3": to_boolean(int8("0")),
+ "t4": to_boolean(int8("10")),
+
+ "t5": to_boolean(int16("0")),
+ "t6": to_boolean(int16("10")),
+
+ "t7": to_boolean(int32("0")),
+ "t8": to_boolean(int32("10")),
+
+ "t9": to_boolean(int64("0")),
+ "t10": to_boolean(int64("10")),
+
+ "t11": to_boolean(float("NaN")),
+ "t12": to_boolean(float("0.0")),
+ "t13": to_boolean(float("-0.0")),
+ "t14": to_boolean(float("2.5")),
+
+ "t15": to_boolean(double("NaN")),
+ "t16": to_boolean(double("0.0")),
+ "t17": to_boolean(double("-0.0")),
+ "t18": to_boolean(double("2.5")),
+
+ "t19": to_boolean(""),
+ "t20": to_boolean(" "),
+ "t21": to_boolean("false"),
+
+ "t22": to_boolean([]),
+ "t23": to_boolean([0]),
+
+ "t24": to_boolean({{}}),
+ "t25": to_boolean({{0}}),
+
+ "t26": to_boolean({}),
+ "t27": to_boolean({ "foo":0 }),
+
+ "t28": is_null(to_boolean(null)),
+ "t29": is_missing(to_boolean(missing))
+}
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_boolean_02/to_boolean_02.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_boolean_02/to_boolean_02.1.query.aql
new file mode 100644
index 0000000..5be147e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_boolean_02/to_boolean_02.1.query.aql
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+{
+ "t": to_boolean(date("2017-06-30"))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_double_01/to_double_01.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_double_01/to_double_01.1.query.aql
new file mode 100644
index 0000000..f16e139
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_double_01/to_double_01.1.query.aql
@@ -0,0 +1,35 @@
+/*
+ * 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": todouble(false),
+ "t2": to-double(true),
+ "t3": to_double(int8("8")),
+ "t4": to_double(int16("16")),
+ "t5": to_double(int32("32")),
+ "t6": to_double(int64("64")),
+ "t7": to_double(float("128")),
+ "t8": to_double(double("256")),
+ "t9": to_double("512"),
+ "t10": is_null(to_double("foo")),
+ "t11": is_null(to_double([])),
+ "t12": is_null(to_double({{}})),
+ "t13": is_null(to_double({})),
+ "t14": is_null(to_double(null)),
+ "t15": is_missing(to_double(missing))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_double_02/to_double_02.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_double_02/to_double_02.1.query.aql
new file mode 100644
index 0000000..4a31e1c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_double_02/to_double_02.1.query.aql
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+{
+ "t": to_double(date("2017-06-30"))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_string_01/to_string_01.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_string_01/to_string_01.1.query.aql
new file mode 100644
index 0000000..2abf4c3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_string_01/to_string_01.1.query.aql
@@ -0,0 +1,34 @@
+/*
+ * 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": tostring(false),
+ "t2": to-string(true),
+ "t3": to_string(int8("8")),
+ "t4": to_string(int16("16")),
+ "t5": to_string(int32("32")),
+ "t6": to_string(int64("64")),
+ "t7": to_string(float("128")),
+ "t8": to_string(double("256")),
+ "t9": to_string("foo"),
+ "t10": is_null(to_string([])),
+ "t11": is_null(to_string({{}})),
+ "t12": is_null(to_string({})),
+ "t13": is_null(to_string(null)),
+ "t14": is_missing(to_string(missing))
+ }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_string_02/to_string_02.1.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_string_02/to_string_02.1.query.aql
new file mode 100644
index 0000000..cdfec14
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_string_02/to_string_02.1.query.aql
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+{
+ "t": to_string(date("2017-06-30"))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_bigint_01/to_bigint_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_bigint_01/to_bigint_01.1.query.sqlpp
new file mode 100644
index 0000000..5138123
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_bigint_01/to_bigint_01.1.query.sqlpp
@@ -0,0 +1,35 @@
+/*
+ * 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": tobigint(false),
+ "t2": to_bigint(true),
+ "t3": to_bigint(int8("8")),
+ "t4": to_bigint(int16("16")),
+ "t5": to_bigint(int32("32")),
+ "t6": to_bigint(int64("64")),
+ "t7": to_bigint(float("1e100")),
+ "t8": to_bigint(double("1e1000")),
+ "t9": to_bigint("512"),
+ "t10": is_null(to_bigint("foo")),
+ "t11": is_null(to_bigint([])),
+ "t12": is_null(to_bigint({{}})),
+ "t13": is_null(to_bigint({})),
+ "t14": is_null(to_bigint(null)),
+ "t15": is_missing(to_bigint(missing))
+};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_bigint_02/to_bigint_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_bigint_02/to_bigint_02.1.query.sqlpp
new file mode 100644
index 0000000..13f482f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_bigint_02/to_bigint_02.1.query.sqlpp
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+{
+ "t": to_bigint(date("2017-06-30"))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_boolean_01/to_boolean_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_boolean_01/to_boolean_01.1.query.sqlpp
new file mode 100644
index 0000000..79dc84e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_boolean_01/to_boolean_01.1.query.sqlpp
@@ -0,0 +1,61 @@
+/*
+ * 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": toboolean(false),
+ "t2": to_boolean(true),
+
+ "t3": to_boolean(int8("0")),
+ "t4": to_boolean(int8("10")),
+
+ "t5": to_boolean(int16("0")),
+ "t6": to_boolean(int16("10")),
+
+ "t7": to_boolean(int32("0")),
+ "t8": to_boolean(int32("10")),
+
+ "t9": to_boolean(int64("0")),
+ "t10": to_boolean(int64("10")),
+
+ "t11": to_boolean(float("NaN")),
+ "t12": to_boolean(float("0.0")),
+ "t13": to_boolean(float("-0.0")),
+ "t14": to_boolean(float("2.5")),
+
+ "t15": to_boolean(double("NaN")),
+ "t16": to_boolean(double("0.0")),
+ "t17": to_boolean(double("-0.0")),
+ "t18": to_boolean(double("2.5")),
+
+ "t19": to_boolean(""),
+ "t20": to_boolean(" "),
+ "t21": to_boolean("false"),
+
+ "t22": to_boolean([]),
+ "t23": to_boolean([0]),
+
+ "t24": to_boolean({{}}),
+ "t25": to_boolean({{0}}),
+
+ "t26": to_boolean({}),
+ "t27": to_boolean({ "foo":0 }),
+
+ "t28": is_null(to_boolean(null)),
+ "t29": is_missing(to_boolean(missing))
+}
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_boolean_02/to_boolean_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_boolean_02/to_boolean_02.1.query.sqlpp
new file mode 100644
index 0000000..5be147e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_boolean_02/to_boolean_02.1.query.sqlpp
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+{
+ "t": to_boolean(date("2017-06-30"))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_double_01/to_double_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_double_01/to_double_01.1.query.sqlpp
new file mode 100644
index 0000000..adbc4a1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_double_01/to_double_01.1.query.sqlpp
@@ -0,0 +1,35 @@
+/*
+ * 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": todouble(false),
+ "t2": to_double(true),
+ "t3": to_double(int8("8")),
+ "t4": to_double(int16("16")),
+ "t5": to_double(int32("32")),
+ "t6": to_double(int64("64")),
+ "t7": to_double(float("128")),
+ "t8": to_double(double("256")),
+ "t9": to_double("512"),
+ "t10": is_null(to_double("foo")),
+ "t11": is_null(to_double([])),
+ "t12": is_null(to_double({{}})),
+ "t13": is_null(to_double({})),
+ "t14": is_null(to_double(null)),
+ "t15": is_missing(to_double(missing))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_double_02/to_double_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_double_02/to_double_02.1.query.sqlpp
new file mode 100644
index 0000000..4a31e1c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_double_02/to_double_02.1.query.sqlpp
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+{
+ "t": to_double(date("2017-06-30"))
+}
\ 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
new file mode 100644
index 0000000..8582521
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp
@@ -0,0 +1,34 @@
+/*
+ * 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": tostring(false),
+ "t2": to_string(true),
+ "t3": to_string(int8("8")),
+ "t4": to_string(int16("16")),
+ "t5": to_string(int32("32")),
+ "t6": to_string(int64("64")),
+ "t7": to_string(float("128")),
+ "t8": to_string(double("256")),
+ "t9": to_string("foo"),
+ "t10": is_null(to_string([])),
+ "t11": is_null(to_string({{}})),
+ "t12": is_null(to_string({})),
+ "t13": is_null(to_string(null)),
+ "t14": is_missing(to_string(missing))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_02/to_string_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_02/to_string_02.1.query.sqlpp
new file mode 100644
index 0000000..cdfec14
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_02/to_string_02.1.query.sqlpp
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+{
+ "t": to_string(date("2017-06-30"))
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_bigint_01/to_bigint_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_bigint_01/to_bigint_01.1.adm
new file mode 100644
index 0000000..a7a42e4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_bigint_01/to_bigint_01.1.adm
@@ -0,0 +1 @@
+{ "t1": 0, "t2": 1, "t3": 8, "t4": 16, "t5": 32, "t6": 64, "t7": 9223372036854775807, "t8": 9223372036854775807, "t9": 512, "t10": true, "t11": true, "t12": true, "t13": true, "t14": true, "t15": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_boolean_01/to_boolean_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_boolean_01/to_boolean_01.1.adm
new file mode 100644
index 0000000..e47f893
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_boolean_01/to_boolean_01.1.adm
@@ -0,0 +1 @@
+{ "t1": false, "t2": true, "t3": false, "t4": true, "t5": false, "t6": true, "t7": false, "t8": true, "t9": false, "t10": true, "t11": false, "t12": false, "t13": false, "t14": true, "t15": false, "t16": false, "t17": false, "t18": true, "t19": false, "t20": true, "t21": true, "t22": false, "t23": true, "t24": false, "t25": true, "t26": false, "t27": true, "t28": true, "t29": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_double_01/to_double_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_double_01/to_double_01.1.adm
new file mode 100644
index 0000000..8c2b420
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_double_01/to_double_01.1.adm
@@ -0,0 +1 @@
+{ "t1": 0.0, "t2": 1.0, "t3": 8.0, "t4": 16.0, "t5": 32.0, "t6": 64.0, "t7": 128.0, "t8": 256.0, "t9": 512.0, "t10": true, "t11": true, "t12": true, "t13": true, "t14": true, "t15": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_string_01/to_string_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_string_01/to_string_01.1.adm
new file mode 100644
index 0000000..83dee03
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_string_01/to_string_01.1.adm
@@ -0,0 +1 @@
+{ "t1": "false", "t2": "true", "t3": "8", "t4": "16", "t5": "32", "t6": "64", "t7": "128.0", "t8": "256.0", "t9": "foo", "t10": true, "t11": true, "t12": true, "t13": true, "t14": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml
index 0b31f17..a5e6fbb 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -7198,6 +7198,50 @@
<output-dir compare="Text">promotion_opentype_field_vs_opentype_field_02</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>
+ </test-case>
+ <test-case FilePath="types">
+ <compilation-unit name="to_boolean_02">
+ <output-dir compare="Text">to_boolean_02</output-dir>
+ <expected-error>ASX0002: Type mismatch</expected-error>
+ </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>
+ </test-case>
+ <test-case FilePath="types">
+ <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-group>
<test-group name="materialization">
<test-case FilePath="materialization">
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 93ba5b0..0ad80c0 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -8492,6 +8492,50 @@
<output-dir compare="Text">ifmissingornull</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>
+ </test-case>
+ <test-case FilePath="types">
+ <compilation-unit name="to_boolean_02">
+ <output-dir compare="Text">to_boolean_02</output-dir>
+ <expected-error>ASX0002: Type mismatch</expected-error>
+ </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>
+ </test-case>
+ <test-case FilePath="types">
+ <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-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 7e8a7fe..5cb22d4 100644
--- a/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md
+++ b/asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md
@@ -261,3 +261,142 @@
The function has an alias `isunknown`.
+
+### to_boolean ###
+ * Syntax:
+
+ to_boolean(expr)
+
+ * Converts input value to a `boolean` 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 `boolean` type then it is returned as is
+ * if the argument is of numeric type then `false` is returned if it is `0` or `NaN`, otherwise `true`
+ * if the argument is of `string` type then `false` is returned if it's empty, otherwise `true`
+ * if the argument is of `array` or `multiset` type then `false` is returned if it's size is `0`, otherwise `true`
+ * if the argument is of `object` type then `false` is returned if it has no fields, otherwise `true`
+ * type error is raised for all other input types
+
+ * Example:
+
+ {
+ "v1": to_boolean(0),
+ "v2": to_boolean(1),
+ "v3": to_boolean(""),
+ "v4": to_boolean("asterix")
+ };
+
+ * The expected result is:
+
+ { "v1": false, "v2": true, "v3": false, "v4": true }
+
+ The function has an alias `toboolean`.
+
+
+### to_bigint ###
+ * Syntax:
+
+ to_bigint(expr)
+
+ * Converts input value to an integer 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 `boolean` type then `1` is returned if it is `true`, `0` if it is `false`
+ * if the argument is of numeric integer type then it is returned as the same value of `bigint` type
+ * if the argument is of numeric `float`/`double` type then it is converted to `bigint` type
+ * if the argument is of `string` type and can be parsed as integer then that integer value is returned,
+ otherwise `null` is returned
+ * if the argument is of `array`/`multiset`/`object` type then `null` is returned
+ * type error is raised for all other input types
+
+ * Example:
+
+ {
+ "v1": to_bigint(false),
+ "v2": to_bigint(true),
+ "v3": to_bigint(10),
+ "v4": to_bigint(float("1e100")),
+ "v5": to_bigint(double("1e1000")),
+ "v6": to_bigint("20")
+ };
+
+ * The expected result is:
+
+ { "v1": 0, "v2": 1, "v3": 10, "v4": 9223372036854775807, "v5": 9223372036854775807, "v6": 20 }
+
+ The function has an alias `tobigint`.
+
+
+### to_double ###
+ * Syntax:
+
+ to_double(expr)
+
+ * Converts input value to a `double` 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 `boolean` type then `1.0` is returned if it is `true`, `0.0` if it is `false`
+ * if the argument is of numeric type then it is returned as the value of `double` type
+ * if the argument is of `string` type and can be parsed as `double` then that `double` value is returned,
+ otherwise `null` is returned
+ * if the argument is of `array`/`multiset`/`object` type then `null` is returned
+ * type error is raised for all other input types
+
+ * Example:
+
+ {
+ "v1": to_double(false),
+ "v2": to_double(true),
+ "v3": to_double(10),
+ "v4": to_double(11.5),
+ "v5": to_double("12.5")
+ };
+
+ * The expected result is:
+
+ { "v1": 0.0, "v2": 1.0, "v3": 10.0, "v4": 11.5, "v5": 12.5 }
+
+ The function has an alias `todouble`.
+
+
+### to_string ###
+ * Syntax:
+
+ to_string(expr)
+
+ * Converts input value to a string 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 `boolean` type then `"true"` is returned if it is `true`, `"false"` if it is `false`
+ * if the argument is of numeric type then its string representation is returned
+ * if the argument is of `string` type then it is returned as is
+ * if the argument is of `array`/`multiset`/`object` type then `null` is returned
+ * type error is raised for all other input types
+
+ * Example:
+
+ {
+ "v1": to_string(false),
+ "v2": to_string(true),
+ "v3": to_string(10),
+ "v4": to_string(11.5),
+ "v5": to_string("asterix")
+ };
+
+ * The expected result is:
+
+ { "v1": "false", "v2": "true", "v3": "10", "v4": "11.5", "v5": "asterix" }
+
+ The function has an alias `tostring`.
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 6a0c05e..092de98 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
@@ -65,6 +65,10 @@
FUNCTION_NAME_MAP.put("ifmissing", "if-missing"); // ifmissing, internal: if-missing
FUNCTION_NAME_MAP.put("ifnull", "if-null"); // ifnull, internal: if-null
FUNCTION_NAME_MAP.put("ifmissingornull", "if-missing-or-null"); // ifmissingornull, internal: is-missing-or-null
+ FUNCTION_NAME_MAP.put("toboolean", "to-boolean"); // toboolean, internal: to-boolean
+ FUNCTION_NAME_MAP.put("tostring", "to-string"); // tostring, internal: to-string
+ FUNCTION_NAME_MAP.put("todouble", "to-double"); // todouble, internal: to-double
+ FUNCTION_NAME_MAP.put("tobigint", "to-bigint"); // tobigint, internal: to-bigint
// Object functions
FUNCTION_NAME_MAP.put("record-merge", "object-merge"); // record-merge, internal: object-merge
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
index 6aee698..fafa397 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java
@@ -308,8 +308,7 @@
public static int getFieldOffsetByName(byte[] serRecord, int start, int len, byte[] fieldName, int nstart)
throws HyracksDataException {
// 5 is the index of the byte that determines whether the record is expanded or not, i.e. it has an open part.
- // a record with len < 5 is empty
- if (serRecord[start] != ATypeTag.SERIALIZED_RECORD_TYPE_TAG || len <= 5 || serRecord[start + 5] != 1) {
+ if (hasNoFields(serRecord, start, len) || serRecord[start + 5] != 1) {
return -1;
}
// 6 is the index of the first byte of the openPartOffset value.
@@ -367,6 +366,11 @@
return -1; // no field with this name.
}
+ public static boolean hasNoFields(byte[] serRecord, int start, int len) {
+ // a record with len <= 6 is empty
+ return serRecord[start] != ATypeTag.SERIALIZED_RECORD_TYPE_TAG || len <= 6;
+ }
+
@Override
public String toString() {
return " ";
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 dbcef6c..695483b 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
@@ -804,6 +804,15 @@
public static final FunctionIdentifier IF_MISSING_OR_NULL = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"if-missing-or-null", 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_BIGINT =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "to-bigint", 1);
+
public static final FunctionIdentifier EXTERNAL_LOOKUP = new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"external-lookup", FunctionIdentifier.VARARGS);
@@ -982,6 +991,11 @@
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, ADoubleTypeComputer.INSTANCE, true);
+ addFunction(TO_BIGINT, AInt64TypeComputer.INSTANCE, true);
+
// Aggregate Functions
addFunction(MAX, MinMaxAggTypeComputer.INSTANCE, true);
addPrivateFunction(LOCAL_MAX, MinMaxAggTypeComputer.INSTANCE, true);
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABooleanConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABooleanConstructorDescriptor.java
index 5ef78d3..2f981b9 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABooleanConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABooleanConstructorDescriptor.java
@@ -18,32 +18,15 @@
*/
package org.apache.asterix.runtime.evaluators.constructors;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import org.apache.asterix.formats.nontagged.BinaryComparatorFactoryProvider;
-import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
-import org.apache.asterix.om.base.ABoolean;
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.om.types.BuiltinType;
import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.exceptions.InvalidDataFormatException;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
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.dataflow.value.IBinaryComparator;
-import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
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;
-import org.apache.hyracks.util.string.UTF8StringUtil;
public class ABooleanConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
@@ -61,62 +44,18 @@
@Override
public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws HyracksDataException {
- return new IScalarEvaluator() {
- private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
- private DataOutput out = resultStorage.getDataOutput();
- private IPointable inputArg = new VoidPointable();
- private IScalarEvaluator eval = args[0].createScalarEvaluator(ctx);
- private final byte[] TRUE = UTF8StringUtil.writeStringToBytes("true");
- private final byte[] FALSE = UTF8StringUtil.writeStringToBytes("false");
- IBinaryComparator utf8BinaryComparator =
- BinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE.createBinaryComparator();
- @SuppressWarnings("unchecked")
- private ISerializerDeserializer<ABoolean> booleanSerde =
- SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ABOOLEAN);
-
+ return new AbstractBooleanConstructorEvaluator(args[0].createScalarEvaluator(ctx)) {
@Override
- public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
- try {
- eval.evaluate(tuple, inputArg);
- byte[] serString = inputArg.getByteArray();
- int startOffset = inputArg.getStartOffset();
- int len = inputArg.getLength();
-
- byte tt = serString[startOffset];
- if (tt == ATypeTag.SERIALIZED_BOOLEAN_TYPE_TAG) {
- result.set(inputArg);
- } else if (tt == ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
- resultStorage.reset();
- if (utf8BinaryComparator.compare(serString, startOffset + 1, len - 1, TRUE, 0,
- TRUE.length) == 0) {
- booleanSerde.serialize(ABoolean.TRUE, out);
- result.set(resultStorage);
- } else if (utf8BinaryComparator.compare(serString, startOffset + 1, len - 1, FALSE, 0,
- FALSE.length) == 0) {
- booleanSerde.serialize(ABoolean.FALSE, out);
- result.set(resultStorage);
- } else {
- throw new InvalidDataFormatException(getIdentifier(),
- ATypeTag.SERIALIZED_BOOLEAN_TYPE_TAG);
- }
- } else {
- throw new TypeMismatchException(getIdentifier(), 0, tt,
- ATypeTag.SERIALIZED_STRING_TYPE_TAG);
- }
- } catch (IOException e) {
- throw new InvalidDataFormatException(getIdentifier(), e,
- ATypeTag.SERIALIZED_BOOLEAN_TYPE_TAG);
- }
+ protected FunctionIdentifier getIdentifier() {
+ return ABooleanConstructorDescriptor.this.getIdentifier();
}
};
}
};
-
}
@Override
public FunctionIdentifier getIdentifier() {
return BuiltinFunctions.BOOLEAN_CONSTRUCTOR;
}
-
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADoubleConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADoubleConstructorDescriptor.java
index 299a452..87df400 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADoubleConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADoubleConstructorDescriptor.java
@@ -18,34 +18,15 @@
*/
package org.apache.asterix.runtime.evaluators.constructors;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import org.apache.asterix.formats.nontagged.BinaryComparatorFactoryProvider;
-import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
-import org.apache.asterix.om.base.ADouble;
-import org.apache.asterix.om.base.AMutableDouble;
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.om.types.BuiltinType;
import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.exceptions.InvalidDataFormatException;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
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.dataflow.value.IBinaryComparator;
-import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.data.std.api.IPointable;
-import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-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;
-import org.apache.hyracks.util.string.UTF8StringUtil;
public class ADoubleConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
@@ -63,59 +44,10 @@
@Override
public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws HyracksDataException {
- return new IScalarEvaluator() {
- private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
- private final DataOutput out = resultStorage.getDataOutput();
- private final IPointable inputArg = new VoidPointable();
- private IScalarEvaluator eval = args[0].createScalarEvaluator(ctx);
- private final byte[] POSITIVE_INF = UTF8StringUtil.writeStringToBytes("INF");
- private final byte[] NEGATIVE_INF = UTF8StringUtil.writeStringToBytes("-INF");
- private final byte[] NAN = UTF8StringUtil.writeStringToBytes("NaN");
- IBinaryComparator utf8BinaryComparator =
- BinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE.createBinaryComparator();
- private AMutableDouble aDouble = new AMutableDouble(0);
- @SuppressWarnings("unchecked")
- private ISerializerDeserializer<ADouble> doubleSerde =
- SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADOUBLE);
-
- private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
-
+ return new AbstractDoubleConstructorEvaluator(args[0].createScalarEvaluator(ctx)) {
@Override
- public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
- try {
- eval.evaluate(tuple, inputArg);
- byte[] serString = inputArg.getByteArray();
- int offset = inputArg.getStartOffset();
- int len = inputArg.getLength();
-
- byte tt = serString[offset];
- if (tt == ATypeTag.SERIALIZED_DOUBLE_TYPE_TAG) {
- result.set(inputArg);
- } else if (tt == ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
- resultStorage.reset();
- if (utf8BinaryComparator.compare(serString, offset + 1, len - 1, POSITIVE_INF, 0,
- 5) == 0) {
- aDouble.setValue(Double.POSITIVE_INFINITY);
- } else if (utf8BinaryComparator.compare(serString, offset + 1, len - 1, NEGATIVE_INF, 0,
- 6) == 0) {
- aDouble.setValue(Double.NEGATIVE_INFINITY);
- } else if (utf8BinaryComparator.compare(serString, offset + 1, len - 1, NAN, 0,
- 5) == 0) {
- aDouble.setValue(Double.NaN);
- } else {
- utf8Ptr.set(serString, offset + 1, len - 1);
- aDouble.setValue(Double.parseDouble(utf8Ptr.toString()));
- }
- doubleSerde.serialize(aDouble, out);
- result.set(resultStorage);
- } else {
- throw new TypeMismatchException(getIdentifier(), 0, tt,
- ATypeTag.SERIALIZED_STRING_TYPE_TAG);
- }
- } catch (IOException e) {
- throw new InvalidDataFormatException(getIdentifier(), e,
- ATypeTag.SERIALIZED_DATETIME_TYPE_TAG);
- }
+ protected FunctionIdentifier getIdentifier() {
+ return ADoubleConstructorDescriptor.this.getIdentifier();
}
};
}
@@ -126,5 +58,4 @@
public FunctionIdentifier getIdentifier() {
return BuiltinFunctions.DOUBLE_CONSTRUCTOR;
}
-
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt64ConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt64ConstructorDescriptor.java
index a2dc8b2..61a35b6 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt64ConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt64ConstructorDescriptor.java
@@ -18,31 +18,15 @@
*/
package org.apache.asterix.runtime.evaluators.constructors;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
-import org.apache.asterix.om.base.AInt64;
-import org.apache.asterix.om.base.AMutableInt64;
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.om.types.BuiltinType;
import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.exceptions.InvalidDataFormatException;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
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.dataflow.value.ISerializerDeserializer;
import org.apache.hyracks.api.exceptions.HyracksDataException;
-import org.apache.hyracks.data.std.api.IPointable;
-import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
-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 AInt64ConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
@@ -60,96 +44,18 @@
@Override
public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws HyracksDataException {
- return new IScalarEvaluator() {
-
- private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
- private DataOutput out = resultStorage.getDataOutput();
- private IPointable inputArg = new VoidPointable();
- private IScalarEvaluator eval = args[0].createScalarEvaluator(ctx);
- private long value;
- private int offset;
- private boolean positive;
- private AMutableInt64 aInt64 = new AMutableInt64(0);
- @SuppressWarnings("unchecked")
- private ISerializerDeserializer<AInt64> int64Serde = SerializerDeserializerProvider.INSTANCE
- .getSerializerDeserializer(BuiltinType.AINT64);
- private final UTF8StringPointable utf8Ptr = new UTF8StringPointable();
-
+ return new AbstractInt64ConstructorEvaluator(args[0].createScalarEvaluator(ctx)) {
@Override
- public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
- try {
- eval.evaluate(tuple, inputArg);
- byte[] serString = inputArg.getByteArray();
- int startOffset = inputArg.getStartOffset();
- int len = inputArg.getLength();
-
- byte tt = serString[startOffset];
- if (tt == ATypeTag.SERIALIZED_INT64_TYPE_TAG) {
- result.set(inputArg);
- } else if (tt == ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
- resultStorage.reset();
- utf8Ptr.set(serString, startOffset + 1, len - 1);
- offset = utf8Ptr.getCharStartOffset();
- //accumulating value in negative domain
- //otherwise Long.MIN_VALUE = -(Long.MAX_VALUE + 1) would have caused overflow
- value = 0;
- positive = true;
- long limit = -Long.MAX_VALUE;
- if (serString[offset] == '+') {
- offset++;
- } else if (serString[offset] == '-') {
- offset++;
- positive = false;
- limit = Long.MIN_VALUE;
- }
- int end = startOffset + len;
- for (; offset < end; offset++) {
- int digit;
- if (serString[offset] >= '0' && serString[offset] <= '9') {
- value *= 10;
- digit = serString[offset] - '0';
- } else if (serString[offset] == 'i' && serString[offset + 1] == '6'
- && serString[offset + 2] == '4' && offset + 3 == end) {
- break;
- } else {
- throw new InvalidDataFormatException(getIdentifier(),
- ATypeTag.SERIALIZED_INT64_TYPE_TAG);
- }
- if (value < limit + digit) {
- throw new InvalidDataFormatException(getIdentifier(),
- ATypeTag.SERIALIZED_INT64_TYPE_TAG);
- }
- value -= digit;
- }
- if (value > 0) {
- throw new InvalidDataFormatException(getIdentifier(),
- ATypeTag.SERIALIZED_INT64_TYPE_TAG);
- }
- if (value < 0 && positive) {
- value *= -1;
- }
-
- aInt64.setValue(value);
- int64Serde.serialize(aInt64, out);
- result.set(resultStorage);
- } else {
- throw new TypeMismatchException(getIdentifier(), 0, tt,
- ATypeTag.SERIALIZED_STRING_TYPE_TAG);
- }
- } catch (IOException e) {
- throw new InvalidDataFormatException(getIdentifier(), e,
- ATypeTag.SERIALIZED_INT64_TYPE_TAG);
- }
+ public FunctionIdentifier getIdentifier() {
+ return AInt64ConstructorDescriptor.this.getIdentifier();
}
};
}
};
-
}
@Override
public FunctionIdentifier getIdentifier() {
return BuiltinFunctions.INT64_CONSTRUCTOR;
}
-
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AStringConstructorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AStringConstructorDescriptor.java
index 3c59c4c..00b5475 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AStringConstructorDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AStringConstructorDescriptor.java
@@ -18,34 +18,15 @@
*/
package org.apache.asterix.runtime.evaluators.constructors;
-import java.io.DataOutput;
-import java.io.IOException;
-
-import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
-import org.apache.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
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.asterix.runtime.exceptions.InvalidDataFormatException;
-import org.apache.asterix.runtime.exceptions.UnsupportedTypeException;
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.data.std.util.GrowableArray;
-import org.apache.hyracks.data.std.util.UTF8StringBuilder;
-import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
public class AStringConstructorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
@@ -64,98 +45,10 @@
@Override
public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws HyracksDataException {
- return new IScalarEvaluator() {
-
- private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
- private DataOutput out = resultStorage.getDataOutput();
- private IPointable inputArg = new VoidPointable();
- private IScalarEvaluator eval = args[0].createScalarEvaluator(ctx);
- private UTF8StringBuilder builder = new UTF8StringBuilder();
- private GrowableArray baaos = new GrowableArray();
-
+ return new AbstractStringConstructorEvaluator(args[0].createScalarEvaluator(ctx)) {
@Override
- public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
- try {
- eval.evaluate(tuple, inputArg);
- byte[] serString = inputArg.getByteArray();
- int offset = inputArg.getStartOffset();
- int len = inputArg.getLength();
-
- ATypeTag tt = ATypeTag.VALUE_TYPE_MAPPING[serString[offset]];
- if (tt == ATypeTag.STRING) {
- result.set(inputArg);
- } else {
- resultStorage.reset();
- baaos.reset();
- builder.reset(baaos, len);
- int startOffset = offset + 1;
- switch (tt) {
- case TINYINT: {
- int i = AInt8SerializerDeserializer.getByte(serString, startOffset);
- builder.appendString(String.valueOf(i));
- break;
- }
- case SMALLINT: {
- int i = AInt16SerializerDeserializer.getShort(serString, startOffset);
- builder.appendString(String.valueOf(i));
- break;
- }
- case INTEGER: {
- int i = AInt32SerializerDeserializer.getInt(serString, startOffset);
- builder.appendString(String.valueOf(i));
- break;
- }
- case BIGINT: {
- long l = AInt64SerializerDeserializer.getLong(serString, startOffset);
- builder.appendString(String.valueOf(l));
- break;
- }
- case DOUBLE: {
- double d = ADoubleSerializerDeserializer.getDouble(serString, startOffset);
- builder.appendString(String.valueOf(d));
- break;
- }
- case FLOAT: {
- float f = AFloatSerializerDeserializer.getFloat(serString, startOffset);
- builder.appendString(String.valueOf(f));
- break;
- }
- case BOOLEAN: {
- boolean b = ABooleanSerializerDeserializer.getBoolean(serString, startOffset);
- builder.appendString(String.valueOf(b));
- break;
- }
-
- // NotYetImplemented
- case CIRCLE:
- case DATE:
- case DATETIME:
- case LINE:
- case TIME:
- case DURATION:
- case YEARMONTHDURATION:
- case DAYTIMEDURATION:
- case INTERVAL:
- case ARRAY:
- case POINT:
- case POINT3D:
- case RECTANGLE:
- case POLYGON:
- case OBJECT:
- case MULTISET:
- case UUID:
- default:
- throw new UnsupportedTypeException(getIdentifier(), serString[offset]);
- }
- builder.finish();
- out.write(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
- out.write(baaos.getByteArray(), 0, baaos.getLength());
- result.set(resultStorage);
- }
- } catch (IOException e) {
- throw new InvalidDataFormatException(getIdentifier(), e,
- ATypeTag.SERIALIZED_STRING_TYPE_TAG);
- }
+ protected FunctionIdentifier getIdentifier() {
+ return AStringConstructorDescriptor.this.getIdentifier();
}
};
}
@@ -166,5 +59,4 @@
public FunctionIdentifier getIdentifier() {
return BuiltinFunctions.STRING_CONSTRUCTOR;
}
-
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractBooleanConstructorEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractBooleanConstructorEvaluator.java
new file mode 100644
index 0000000..9b9bf71
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractBooleanConstructorEvaluator.java
@@ -0,0 +1,103 @@
+/*
+ * 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.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.formats.nontagged.BinaryComparatorFactoryProvider;
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.ABoolean;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.runtime.exceptions.InvalidDataFormatException;
+import org.apache.asterix.runtime.exceptions.TypeMismatchException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.dataflow.value.IBinaryComparator;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+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;
+import org.apache.hyracks.util.string.UTF8StringUtil;
+
+public abstract class AbstractBooleanConstructorEvaluator implements IScalarEvaluator {
+ @SuppressWarnings("unchecked")
+ protected static final ISerializerDeserializer<ABoolean> BOOLEAN_SERDE =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ABOOLEAN);
+
+ protected static final IBinaryComparator UTF8_BINARY_CMP =
+ BinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE.createBinaryComparator();
+
+ protected static final byte[] TRUE = UTF8StringUtil.writeStringToBytes("true");
+ protected static final byte[] FALSE = UTF8StringUtil.writeStringToBytes("false");
+
+ protected final IScalarEvaluator inputEval;
+ protected final IPointable inputArg;
+ protected final ArrayBackedValueStorage resultStorage;
+ protected final DataOutput out;
+
+ protected AbstractBooleanConstructorEvaluator(IScalarEvaluator inputEval) {
+ this.inputEval = inputEval;
+ inputArg = new VoidPointable();
+ resultStorage = new ArrayBackedValueStorage();
+ out = resultStorage.getDataOutput();
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ try {
+ inputEval.evaluate(tuple, inputArg);
+ resultStorage.reset();
+ evaluateImpl(result);
+ } catch (IOException e) {
+ throw new InvalidDataFormatException(getIdentifier(), e, ATypeTag.SERIALIZED_BOOLEAN_TYPE_TAG);
+ }
+ }
+
+ protected void evaluateImpl(IPointable result) throws HyracksDataException {
+ byte[] bytes = inputArg.getByteArray();
+ int startOffset = inputArg.getStartOffset();
+ byte tt = bytes[startOffset];
+ if (tt == ATypeTag.SERIALIZED_BOOLEAN_TYPE_TAG) {
+ result.set(inputArg);
+ } else if (tt == ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+ int len = inputArg.getLength();
+ if (UTF8_BINARY_CMP.compare(bytes, startOffset + 1, len - 1, TRUE, 0, TRUE.length) == 0) {
+ setBoolean(result, true);
+ } else if (UTF8_BINARY_CMP.compare(bytes, startOffset + 1, len - 1, FALSE, 0, FALSE.length) == 0) {
+ setBoolean(result, false);
+ } else {
+ throw new InvalidDataFormatException(getIdentifier(), ATypeTag.SERIALIZED_BOOLEAN_TYPE_TAG);
+ }
+ } else {
+ throw new TypeMismatchException(getIdentifier(), 0, tt, ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+ }
+ }
+
+ protected void setBoolean(IPointable result, boolean value) throws HyracksDataException {
+ BOOLEAN_SERDE.serialize(ABoolean.valueOf(value), out);
+ result.set(resultStorage);
+ }
+
+ protected abstract FunctionIdentifier getIdentifier();
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDoubleConstructorEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDoubleConstructorEvaluator.java
new file mode 100644
index 0000000..332bfc2
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDoubleConstructorEvaluator.java
@@ -0,0 +1,122 @@
+/*
+ * 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.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.formats.nontagged.BinaryComparatorFactoryProvider;
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.ADouble;
+import org.apache.asterix.om.base.AMutableDouble;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.runtime.exceptions.InvalidDataFormatException;
+import org.apache.asterix.runtime.exceptions.TypeMismatchException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.dataflow.value.IBinaryComparator;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+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;
+import org.apache.hyracks.util.string.UTF8StringUtil;
+
+public abstract class AbstractDoubleConstructorEvaluator implements IScalarEvaluator {
+ @SuppressWarnings("unchecked")
+ protected static final ISerializerDeserializer<ADouble> DOUBLE_SERDE =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADOUBLE);
+
+ protected static final IBinaryComparator UTF8_BINARY_CMP =
+ BinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE.createBinaryComparator();
+
+ protected static final byte[] POSITIVE_INF = UTF8StringUtil.writeStringToBytes("INF");
+ protected static final byte[] NEGATIVE_INF = UTF8StringUtil.writeStringToBytes("-INF");
+ protected static final byte[] NAN = UTF8StringUtil.writeStringToBytes("NaN");
+
+ protected final IScalarEvaluator inputEval;
+ protected final ArrayBackedValueStorage resultStorage;
+ protected final DataOutput out;
+ protected final IPointable inputArg;
+ protected final AMutableDouble aDouble;
+ protected final UTF8StringPointable utf8Ptr;
+
+ protected AbstractDoubleConstructorEvaluator(IScalarEvaluator inputEval) {
+ this.inputEval = inputEval;
+ resultStorage = new ArrayBackedValueStorage();
+ out = resultStorage.getDataOutput();
+ inputArg = new VoidPointable();
+ aDouble = new AMutableDouble(0);
+ utf8Ptr = new UTF8StringPointable();
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ try {
+ inputEval.evaluate(tuple, inputArg);
+ resultStorage.reset();
+ evaluateImpl(result);
+ } catch (IOException e) {
+ throw new InvalidDataFormatException(getIdentifier(), e, ATypeTag.SERIALIZED_DOUBLE_TYPE_TAG);
+ }
+ }
+
+ protected void evaluateImpl(IPointable result) throws IOException {
+ byte[] bytes = inputArg.getByteArray();
+ int offset = inputArg.getStartOffset();
+ byte tt = bytes[offset];
+ if (tt == ATypeTag.SERIALIZED_DOUBLE_TYPE_TAG) {
+ result.set(inputArg);
+ } else if (tt == ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+ int len = inputArg.getLength();
+ if (UTF8_BINARY_CMP.compare(bytes, offset + 1, len - 1, POSITIVE_INF, 0, 5) == 0) {
+ setDouble(result, Double.POSITIVE_INFINITY);
+ } else if (UTF8_BINARY_CMP.compare(bytes, offset + 1, len - 1, NEGATIVE_INF, 0, 6) == 0) {
+ setDouble(result, Double.NEGATIVE_INFINITY);
+ } else if (UTF8_BINARY_CMP.compare(bytes, offset + 1, len - 1, NAN, 0, 5) == 0) {
+ setDouble(result, Double.NaN);
+ } else {
+ utf8Ptr.set(bytes, offset + 1, len - 1);
+ try {
+ setDouble(result, Double.parseDouble(utf8Ptr.toString()));
+ } catch (NumberFormatException e) {
+ handleUparseableString(result, e);
+ }
+ }
+ } else {
+ throw new TypeMismatchException(getIdentifier(), 0, tt, ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+ }
+ }
+
+ protected void handleUparseableString(IPointable result, NumberFormatException e) throws HyracksDataException {
+ throw new InvalidDataFormatException(getIdentifier(), e, ATypeTag.SERIALIZED_DOUBLE_TYPE_TAG);
+ }
+
+ protected void setDouble(IPointable result, double value) throws HyracksDataException {
+ aDouble.setValue(value);
+ DOUBLE_SERDE.serialize(aDouble, out);
+ result.set(resultStorage);
+ }
+
+ protected abstract FunctionIdentifier getIdentifier();
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt64ConstructorEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt64ConstructorEvaluator.java
new file mode 100644
index 0000000..8cf9bed
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt64ConstructorEvaluator.java
@@ -0,0 +1,135 @@
+/*
+ * 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.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AInt64;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.runtime.exceptions.InvalidDataFormatException;
+import org.apache.asterix.runtime.exceptions.TypeMismatchException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+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 abstract class AbstractInt64ConstructorEvaluator implements IScalarEvaluator {
+ @SuppressWarnings("unchecked")
+ protected static final ISerializerDeserializer<AInt64> INT64_SERDE =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64);
+
+ protected final IScalarEvaluator inputEval;
+ protected final IPointable inputArg;
+ protected final ArrayBackedValueStorage resultStorage;
+ protected final DataOutput out;
+ protected final AMutableInt64 aInt64;
+ protected final UTF8StringPointable utf8Ptr;
+
+ protected AbstractInt64ConstructorEvaluator(IScalarEvaluator inputEval) {
+ this.inputEval = inputEval;
+ inputArg = new VoidPointable();
+ resultStorage = new ArrayBackedValueStorage();
+ out = resultStorage.getDataOutput();
+ aInt64 = new AMutableInt64(0);
+ utf8Ptr = new UTF8StringPointable();
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ try {
+ inputEval.evaluate(tuple, inputArg);
+ resultStorage.reset();
+ evaluateImpl(result);
+ } catch (IOException e) {
+ throw new InvalidDataFormatException(getIdentifier(), e, ATypeTag.SERIALIZED_INT64_TYPE_TAG);
+ }
+ }
+
+ protected void evaluateImpl(IPointable result) throws IOException {
+ byte[] bytes = inputArg.getByteArray();
+ int startOffset = inputArg.getStartOffset();
+
+ byte tt = bytes[startOffset];
+ if (tt == ATypeTag.SERIALIZED_INT64_TYPE_TAG) {
+ result.set(inputArg);
+ } else if (tt == ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
+ int len = inputArg.getLength();
+ utf8Ptr.set(bytes, startOffset + 1, len - 1);
+ int offset = utf8Ptr.getCharStartOffset();
+ //accumulating value in negative domain
+ //otherwise Long.MIN_VALUE = -(Long.MAX_VALUE + 1) would have caused overflow
+ long value = 0;
+ boolean positive = true;
+ long limit = -Long.MAX_VALUE;
+ if (bytes[offset] == '+') {
+ offset++;
+ } else if (bytes[offset] == '-') {
+ offset++;
+ positive = false;
+ limit = Long.MIN_VALUE;
+ }
+ int end = startOffset + len;
+ for (; offset < end; offset++) {
+ int digit;
+ if (bytes[offset] >= '0' && bytes[offset] <= '9') {
+ value *= 10;
+ digit = bytes[offset] - '0';
+ } else if (bytes[offset] == 'i' && bytes[offset + 1] == '6' && bytes[offset + 2] == '4'
+ && offset + 3 == end) {
+ break;
+ } else {
+ handleUnparseableString(result);
+ return;
+ }
+ if (value < limit + digit) {
+ handleUnparseableString(result);
+ }
+ value -= digit;
+ }
+ if (value > 0) {
+ handleUnparseableString(result);
+ }
+ if (value < 0 && positive) {
+ value *= -1;
+ }
+
+ aInt64.setValue(value);
+ INT64_SERDE.serialize(aInt64, out);
+ result.set(resultStorage);
+ } else {
+ throw new TypeMismatchException(getIdentifier(), 0, tt, ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+ }
+ }
+
+ protected void handleUnparseableString(IPointable result) throws HyracksDataException {
+ throw new InvalidDataFormatException(getIdentifier(), ATypeTag.SERIALIZED_INT64_TYPE_TAG);
+ }
+
+ protected abstract FunctionIdentifier getIdentifier();
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractStringConstructorEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractStringConstructorEvaluator.java
new file mode 100644
index 0000000..6918bb9
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractStringConstructorEvaluator.java
@@ -0,0 +1,152 @@
+/*
+ * 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.constructors;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.runtime.exceptions.InvalidDataFormatException;
+import org.apache.asterix.runtime.exceptions.UnsupportedTypeException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.data.std.util.GrowableArray;
+import org.apache.hyracks.data.std.util.UTF8StringBuilder;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public abstract class AbstractStringConstructorEvaluator implements IScalarEvaluator {
+
+ protected final IScalarEvaluator inputEval;
+ protected final IPointable inputArg;
+ protected final ArrayBackedValueStorage resultStorage;
+ protected final DataOutput out;
+ protected final UTF8StringBuilder builder;
+ protected final GrowableArray baaos;
+
+ protected AbstractStringConstructorEvaluator(IScalarEvaluator inputEval) {
+ resultStorage = new ArrayBackedValueStorage();
+ out = resultStorage.getDataOutput();
+ inputArg = new VoidPointable();
+ this.inputEval = inputEval;
+ builder = new UTF8StringBuilder();
+ baaos = new GrowableArray();
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ try {
+ inputEval.evaluate(tuple, inputArg);
+ resultStorage.reset();
+ evaluateImpl(result);
+ } catch (IOException e) {
+ throw new InvalidDataFormatException(getIdentifier(), e, ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+ }
+ }
+
+ protected void evaluateImpl(IPointable result) throws IOException {
+ byte[] serString = inputArg.getByteArray();
+ int offset = inputArg.getStartOffset();
+
+ ATypeTag tt = ATypeTag.VALUE_TYPE_MAPPING[serString[offset]];
+ if (tt == ATypeTag.STRING) {
+ result.set(inputArg);
+ } else {
+ int len = inputArg.getLength();
+ baaos.reset();
+ builder.reset(baaos, len);
+ int startOffset = offset + 1;
+ switch (tt) {
+ case TINYINT: {
+ int i = AInt8SerializerDeserializer.getByte(serString, startOffset);
+ builder.appendString(String.valueOf(i));
+ break;
+ }
+ case SMALLINT: {
+ int i = AInt16SerializerDeserializer.getShort(serString, startOffset);
+ builder.appendString(String.valueOf(i));
+ break;
+ }
+ case INTEGER: {
+ int i = AInt32SerializerDeserializer.getInt(serString, startOffset);
+ builder.appendString(String.valueOf(i));
+ break;
+ }
+ case BIGINT: {
+ long l = AInt64SerializerDeserializer.getLong(serString, startOffset);
+ builder.appendString(String.valueOf(l));
+ break;
+ }
+ case DOUBLE: {
+ double d = ADoubleSerializerDeserializer.getDouble(serString, startOffset);
+ builder.appendString(String.valueOf(d));
+ break;
+ }
+ case FLOAT: {
+ float f = AFloatSerializerDeserializer.getFloat(serString, startOffset);
+ builder.appendString(String.valueOf(f));
+ break;
+ }
+ case BOOLEAN: {
+ boolean b = ABooleanSerializerDeserializer.getBoolean(serString, startOffset);
+ builder.appendString(String.valueOf(b));
+ break;
+ }
+
+ // NotYetImplemented
+ case CIRCLE:
+ case DATE:
+ case DATETIME:
+ case LINE:
+ case TIME:
+ case DURATION:
+ case YEARMONTHDURATION:
+ case DAYTIMEDURATION:
+ case INTERVAL:
+ case ARRAY:
+ case POINT:
+ case POINT3D:
+ case RECTANGLE:
+ case POLYGON:
+ case OBJECT:
+ case MULTISET:
+ case UUID:
+ default:
+ throw new UnsupportedTypeException(getIdentifier(), serString[offset]);
+ }
+ builder.finish();
+ out.write(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+ out.write(baaos.getByteArray(), 0, baaos.getLength());
+ result.set(resultStorage);
+ }
+ }
+
+ protected abstract FunctionIdentifier getIdentifier();
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToBigIntDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToBigIntDescriptor.java
new file mode 100644
index 0000000..5cf9af7
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToBigIntDescriptor.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.ANull;
+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.om.types.BuiltinType;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.asterix.om.types.hierachy.ITypeConvertComputer;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.constructors.AbstractInt64ConstructorEvaluator;
+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.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+
+public class ToBigIntDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ToBigIntDescriptor();
+ }
+ };
+
+ @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 AbstractInt64ConstructorEvaluator(args[0].createScalarEvaluator(ctx)) {
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<ANull> nullSerde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ protected void evaluateImpl(IPointable result) throws IOException {
+ byte[] bytes = inputArg.getByteArray();
+ int offset = inputArg.getStartOffset();
+ ATypeTag tt = ATypeTag.VALUE_TYPE_MAPPING[bytes[offset]];
+ switch (tt) {
+ case BOOLEAN:
+ boolean b = ABooleanSerializerDeserializer.getBoolean(bytes, offset + 1);
+ aInt64.setValue(b ? 1 : 0);
+ INT64_SERDE.serialize(aInt64, out);
+ result.set(resultStorage);
+ break;
+
+ case TINYINT:
+ case SMALLINT:
+ case INTEGER:
+ ITypeConvertComputer tpcc = ATypeHierarchy.getTypePromoteComputer(tt, ATypeTag.BIGINT);
+ tpcc.convertType(bytes, offset + 1, inputArg.getLength() - 1, out);
+ result.set(resultStorage);
+ break;
+
+ case FLOAT:
+ case DOUBLE:
+ ITypeConvertComputer tdcc =
+ ATypeHierarchy.getTypeDemoteComputer(tt, ATypeTag.BIGINT, false);
+ tdcc.convertType(bytes, offset + 1, inputArg.getLength() - 1, out);
+ result.set(resultStorage);
+ break;
+
+ case ARRAY:
+ case MULTISET:
+ case OBJECT:
+ setNull(result);
+ break;
+
+ default:
+ super.evaluateImpl(result);
+ break;
+ }
+ }
+
+ @Override
+ protected void handleUnparseableString(IPointable result) throws HyracksDataException {
+ setNull(result);
+ }
+
+ private void setNull(IPointable result) throws HyracksDataException {
+ nullSerde.serialize(ANull.NULL, out);
+ result.set(resultStorage);
+ }
+
+ @Override
+ protected FunctionIdentifier getIdentifier() {
+ return ToBigIntDescriptor.this.getIdentifier();
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.TO_BIGINT;
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToBooleanDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToBooleanDescriptor.java
new file mode 100644
index 0000000..ae6aca5
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToBooleanDescriptor.java
@@ -0,0 +1,138 @@
+/*
+ * 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 org.apache.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt16SerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt32SerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt64SerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AInt8SerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.ARecordSerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AUnorderedListSerializerDeserializer;
+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.asterix.runtime.evaluators.constructors.AbstractBooleanConstructorEvaluator;
+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.util.string.UTF8StringUtil;
+
+public class ToBooleanDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ private static final long BITS_NAN = Double.doubleToLongBits(Double.NaN);
+
+ private static final long BITS_ZERO_POS = Double.doubleToLongBits(+0.0d);
+
+ private static final long BITS_ZERO_NEG = Double.doubleToLongBits(-0.0d);
+
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ToBooleanDescriptor();
+ }
+ };
+
+ @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 AbstractBooleanConstructorEvaluator(args[0].createScalarEvaluator(ctx)) {
+ @Override
+ protected void evaluateImpl(IPointable result) throws HyracksDataException {
+ byte[] bytes = inputArg.getByteArray();
+ int offset = inputArg.getStartOffset();
+
+ ATypeTag tt = ATypeTag.VALUE_TYPE_MAPPING[bytes[offset]];
+ switch (tt) {
+ case TINYINT:
+ setInteger(AInt8SerializerDeserializer.getByte(bytes, offset + 1), result);
+ break;
+ case SMALLINT:
+ setInteger(AInt16SerializerDeserializer.getShort(bytes, offset + 1), result);
+ break;
+ case INTEGER:
+ setInteger(AInt32SerializerDeserializer.getInt(bytes, offset + 1), result);
+ break;
+ case BIGINT:
+ setInteger(AInt64SerializerDeserializer.getLong(bytes, offset + 1), result);
+ break;
+ case FLOAT:
+ setDouble(AFloatSerializerDeserializer.getFloat(bytes, offset + 1), result);
+ break;
+ case DOUBLE:
+ setDouble(ADoubleSerializerDeserializer.getDouble(bytes, offset + 1), result);
+ break;
+ case STRING:
+ setInteger(UTF8StringUtil.getStringLength(bytes, offset + 1), result);
+ break;
+ case ARRAY:
+ setInteger(AOrderedListSerializerDeserializer.getNumberOfItems(bytes, offset),
+ result);
+ break;
+ case MULTISET:
+ setInteger(AUnorderedListSerializerDeserializer.getNumberOfItems(bytes, offset),
+ result);
+ break;
+ case OBJECT:
+ setBoolean(result, !ARecordSerializerDeserializer.hasNoFields(bytes, offset,
+ inputArg.getLength()));
+ break;
+ default:
+ super.evaluateImpl(result);
+ break;
+ }
+ }
+
+ private void setInteger(long v, IPointable result) throws HyracksDataException {
+ setBoolean(result, v != 0);
+ }
+
+ private void setDouble(double v, IPointable result) throws HyracksDataException {
+ long bits = Double.doubleToLongBits(v);
+ boolean zeroOrNaN = bits == BITS_ZERO_POS || bits == BITS_ZERO_NEG || bits == BITS_NAN;
+ setBoolean(result, !zeroOrNaN);
+ }
+
+ @Override
+ protected FunctionIdentifier getIdentifier() {
+ return ToBooleanDescriptor.this.getIdentifier();
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.TO_BOOLEAN;
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToDoubleDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToDoubleDescriptor.java
new file mode 100644
index 0000000..a7e4d94
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToDoubleDescriptor.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions;
+
+import java.io.IOException;
+
+import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.ANull;
+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.om.types.BuiltinType;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.asterix.om.types.hierachy.ITypeConvertComputer;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.constructors.AbstractDoubleConstructorEvaluator;
+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.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+
+public class ToDoubleDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ToDoubleDescriptor();
+ }
+ };
+
+ @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 AbstractDoubleConstructorEvaluator(args[0].createScalarEvaluator(ctx)) {
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<ANull> nullSerde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ protected void evaluateImpl(IPointable result) throws IOException {
+ byte[] bytes = inputArg.getByteArray();
+ int offset = inputArg.getStartOffset();
+ ATypeTag tt = ATypeTag.VALUE_TYPE_MAPPING[bytes[offset]];
+ switch (tt) {
+ case BOOLEAN:
+ boolean b = ABooleanSerializerDeserializer.getBoolean(bytes, offset + 1);
+ aDouble.setValue(b ? 1 : 0);
+ DOUBLE_SERDE.serialize(aDouble, out);
+ result.set(resultStorage);
+ break;
+
+ case TINYINT:
+ case SMALLINT:
+ case INTEGER:
+ case BIGINT:
+ case FLOAT:
+ ITypeConvertComputer tcc = ATypeHierarchy.getTypePromoteComputer(tt, ATypeTag.DOUBLE);
+ tcc.convertType(bytes, offset + 1, inputArg.getLength() - 1, out);
+ result.set(resultStorage);
+ break;
+
+ case ARRAY:
+ case MULTISET:
+ case OBJECT:
+ setNull(result);
+ break;
+
+ default:
+ super.evaluateImpl(result);
+ break;
+ }
+ }
+
+ @Override
+ protected void handleUparseableString(IPointable result, NumberFormatException e)
+ throws HyracksDataException {
+ setNull(result);
+ }
+
+ private void setNull(IPointable result) throws HyracksDataException {
+ nullSerde.serialize(ANull.NULL, out);
+ result.set(resultStorage);
+ }
+
+ @Override
+ protected FunctionIdentifier getIdentifier() {
+ return ToDoubleDescriptor.this.getIdentifier();
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.TO_DOUBLE;
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToStringDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToStringDescriptor.java
new file mode 100644
index 0000000..9559da4
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToStringDescriptor.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 org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.ANull;
+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.om.types.BuiltinType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.constructors.AbstractStringConstructorEvaluator;
+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.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+
+import java.io.IOException;
+
+public class ToStringDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ToStringDescriptor();
+ }
+ };
+
+ @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 AbstractStringConstructorEvaluator(args[0].createScalarEvaluator(ctx)) {
+ @SuppressWarnings("unchecked")
+ private final ISerializerDeserializer<ANull> nullSerde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ANULL);
+
+ @Override
+ protected void evaluateImpl(IPointable result) throws IOException {
+ byte[] bytes = inputArg.getByteArray();
+ int offset = inputArg.getStartOffset();
+ ATypeTag tt = ATypeTag.VALUE_TYPE_MAPPING[bytes[offset]];
+ switch (tt) {
+ case ARRAY:
+ case MULTISET:
+ case OBJECT:
+ setNull(result);
+ break;
+ default:
+ super.evaluateImpl(result);
+ break;
+ }
+ }
+
+ private void setNull(IPointable result) throws HyracksDataException {
+ nullSerde.serialize(ANull.NULL, out);
+ result.set(resultStorage);
+ }
+
+ @Override
+ protected FunctionIdentifier getIdentifier() {
+ return ToStringDescriptor.this.getIdentifier();
+ }
+ };
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.TO_STRING;
+ }
+}