Dmitry Lychagin has submitted this change and it was merged. Change subject: [ASTERIXDB-1964][FUN] Add type conversion functions ......................................................................
[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 <jenk...@fulliautomatix.ics.uci.edu> Reviewed-by: Yingyi Bu <buyin...@gmail.com> Tested-by: Jenkins <jenk...@fulliautomatix.ics.uci.edu> --- M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java A asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_bigint_01/to_bigint_01.1.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_bigint_02/to_bigint_02.1.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_boolean_01/to_boolean_01.1.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_boolean_02/to_boolean_02.1.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_double_01/to_double_01.1.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_double_02/to_double_02.1.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_string_01/to_string_01.1.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/types/to_string_02/to_string_02.1.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_bigint_01/to_bigint_01.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_bigint_02/to_bigint_02.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_boolean_01/to_boolean_01.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_boolean_02/to_boolean_02.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_double_01/to_double_01.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_double_02/to_double_02.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_01/to_string_01.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/to_string_02/to_string_02.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_bigint_01/to_bigint_01.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_boolean_01/to_boolean_01.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_double_01/to_double_01.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/types/to_string_01/to_string_01.1.adm M asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml M asterixdb/asterix-doc/src/main/markdown/builtins/11_type.md M asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/ARecordSerializerDeserializer.java M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ABooleanConstructorDescriptor.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/ADoubleConstructorDescriptor.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AInt64ConstructorDescriptor.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AStringConstructorDescriptor.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractBooleanConstructorEvaluator.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractDoubleConstructorEvaluator.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractInt64ConstructorEvaluator.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/constructors/AbstractStringConstructorEvaluator.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToBigIntDescriptor.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToBooleanDescriptor.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToDoubleDescriptor.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ToStringDescriptor.java 39 files changed, 1,776 insertions(+), 349 deletions(-) Approvals: Yingyi Bu: Looks good to me, approved Jenkins: Verified; Verified Objections: Jenkins: Violations found 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; + } +} -- To view, visit https://asterix-gerrit.ics.uci.edu/1861 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7cf119d8a5dd172f4ce2402315fabf7db084559c Gerrit-PatchSet: 4 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Dmitry Lychagin <dmitry.lycha...@couchbase.com> Gerrit-Reviewer: Dmitry Lychagin <dmitry.lycha...@couchbase.com> Gerrit-Reviewer: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Gerrit-Reviewer: Till Westmann <ti...@apache.org> Gerrit-Reviewer: Yingyi Bu <buyin...@gmail.com>