Hussain Towaileb has submitted this change and it was merged. ( https://asterix-gerrit.ics.uci.edu/3433 )
Change subject: [ASTERIXDB-2584][FUN] Support rounding digit for round() ...................................................................... [ASTERIXDB-2584][FUN] Support rounding digit for round() - user model changes: yes - user can pass optional 2nd argument to round() function to specify the digit to round to. - storage format changes: no - interface changes: no Details: - Added new descriptor for 2-arguments version of round(). - Converted evaluator class to named class, now used by both round() descriptors. - Added test cases for 2-arguments version and invalid cases. Change-Id: Ibdde2745e8bc440556e45ed07262eb33327f842b Reviewed-on: https://asterix-gerrit.ics.uci.edu/3433 Contrib: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Tested-by: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Integration-Tests: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Reviewed-by: Hussain Towaileb <hussai...@gmail.com> Reviewed-by: Dmitry Lychagin <dmitry.lycha...@couchbase.com> --- A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round10_with_digit_double/round10_with_digit_double.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round11_invalid/round11_invalid.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round5_with_digit_int8/round5_with_digit_int8.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round6_with_digit_int16/round6_with_digit_int16.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round7_with_digit_int32/round7_with_digit_int32.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round8_with_digit_int64/round8_with_digit_int64.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round9_with_digit_float/round9_with_digit_float.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round10_with_digit_double/round10_with_digit_double.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round11_invalid/round11_invalid.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round5_with_digit_int8/round5_with_digit_int8.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round6_with_digit_int16/round6_with_digit_int16.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round7_with_digit_int32/round6_with_digit_int16.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round8_with_digit_int64/round8_with_digit_int64.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round9_with_digit_float/round9_with_digit_float.1.adm M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml M asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRoundFunctionTypeComputer.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundDescriptor.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundEvaluator.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundWithRoundDigitDescriptor.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java 21 files changed, 650 insertions(+), 107 deletions(-) Approvals: Jenkins: Verified; ; Verified Hussain Towaileb: Looks good to me, but someone else must approve Anon. E. Moose (1000171): Dmitry Lychagin: Looks good to me, approved Objections: Jenkins: Violations found diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round10_with_digit_double/round10_with_digit_double.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round10_with_digit_double/round10_with_digit_double.1.query.sqlpp new file mode 100644 index 0000000..6feb726 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round10_with_digit_double/round10_with_digit_double.1.query.sqlpp @@ -0,0 +1,27 @@ +/* + * 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. + */ + +{ +"f1": round(456.456, 0), +"f2": round(456.456, 2), +"f3": round(456.456, -1), +"f4": round(-456.456, -2), +"f5": round(456.456, 5), +"f6": round(-456.456, -3) +}; \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round11_invalid/round11_invalid.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round11_invalid/round11_invalid.1.query.sqlpp new file mode 100644 index 0000000..d994728 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round11_invalid/round11_invalid.1.query.sqlpp @@ -0,0 +1,28 @@ +/* + * 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. + */ + +{ +"f1": round("abc", 0) IS NULL, +"f2": round(null, 2) IS NULL, +"f3": round(null, missing) IS MISSING, +"f4": round(50, "abc") IS NULL, +"f5": round(456.456, true) IS NULL, +"f6": round(missing, null) IS MISSING, +"f7": round(12345, 1.2) IS NULL +}; \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round5_with_digit_int8/round5_with_digit_int8.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round5_with_digit_int8/round5_with_digit_int8.1.query.sqlpp new file mode 100644 index 0000000..36c7e21 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round5_with_digit_int8/round5_with_digit_int8.1.query.sqlpp @@ -0,0 +1,28 @@ +/* + * 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. + */ + +{ +"f1": round(int8("127"), 0), +"f2": round(int8("127"), 1), +"f3": round(int8("127"), -1), +"f4": round(int8("127"), float("-1.0")), +"f5": round(int8("127"), -1.0), +"f6": round(int8("-127"), -2), +"f7": round(int8("127"), -3) +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round6_with_digit_int16/round6_with_digit_int16.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round6_with_digit_int16/round6_with_digit_int16.1.query.sqlpp new file mode 100644 index 0000000..7dcf7b7 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round6_with_digit_int16/round6_with_digit_int16.1.query.sqlpp @@ -0,0 +1,26 @@ +/* + * 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. + */ + +{ +"f1": round(int16("15345"), 0), +"f2": round(int16("15345"), 1), +"f3": round(int16("15345"), -2), +"f4": round(int16("-15345"), -4), +"f5": round(int16("15345"), -5) +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round7_with_digit_int32/round7_with_digit_int32.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round7_with_digit_int32/round7_with_digit_int32.1.query.sqlpp new file mode 100644 index 0000000..338f3a5 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round7_with_digit_int32/round7_with_digit_int32.1.query.sqlpp @@ -0,0 +1,27 @@ +/* + * 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. + */ + +{ +"f1": round(int32("2147483647"), 0), +"f2": round(int32("2147483647"), 1), +"f3": round(int32("2147483647"), -1), +"f4": round(int32("-2147483647"), -4), +"f5": round(int32("2147483647"), -5), +"f6": round(int32("-2147483647"), -10) +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round8_with_digit_int64/round8_with_digit_int64.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round8_with_digit_int64/round8_with_digit_int64.1.query.sqlpp new file mode 100644 index 0000000..01c128a --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round8_with_digit_int64/round8_with_digit_int64.1.query.sqlpp @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// f4 will underflow, and will result in the lowest possible int64 value +// f5 will overflow, and will result in the maximum possible int64 value + +{ +"f1": round(9223372036854775807, 0), +"f2": round(9223372036854775807, 1), +"f3": round(123456, -1), +"f4": round(-9223372036854775807, -4), +"f5": round(9223372036854775807, -5), +"f6": round(-9223372036854775807, -11) +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round9_with_digit_float/round9_with_digit_float.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round9_with_digit_float/round9_with_digit_float.1.query.sqlpp new file mode 100644 index 0000000..58c587c --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/round9_with_digit_float/round9_with_digit_float.1.query.sqlpp @@ -0,0 +1,27 @@ +/* + * 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. + */ + +{ +"f1": round(float("456.456"), 0), +"f2": round(float("456.456"), 2), +"f3": round(float("456.456"), -1), +"f4": round(float("-456.456"), -2), +"f5": round(float("456.456"), 5), +"f6": round(float("-456.456"), -3) +}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round10_with_digit_double/round10_with_digit_double.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round10_with_digit_double/round10_with_digit_double.1.adm new file mode 100644 index 0000000..cb2517f --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round10_with_digit_double/round10_with_digit_double.1.adm @@ -0,0 +1 @@ +{ "f1": 456.0, "f2": 456.46, "f3": 460.0, "f4": -500.0, "f5": 456.456, "f6": 0.0 } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round11_invalid/round11_invalid.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round11_invalid/round11_invalid.1.adm new file mode 100644 index 0000000..3a6d78e --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round11_invalid/round11_invalid.1.adm @@ -0,0 +1 @@ +{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true, "f7": true } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round5_with_digit_int8/round5_with_digit_int8.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round5_with_digit_int8/round5_with_digit_int8.1.adm new file mode 100644 index 0000000..ef36ff9 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round5_with_digit_int8/round5_with_digit_int8.1.adm @@ -0,0 +1 @@ +{ "f1": 127, "f2": 127, "f3": 130, "f4": 130, "f5": 130, "f6": -100, "f7": 0 } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round6_with_digit_int16/round6_with_digit_int16.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round6_with_digit_int16/round6_with_digit_int16.1.adm new file mode 100644 index 0000000..059f677 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round6_with_digit_int16/round6_with_digit_int16.1.adm @@ -0,0 +1 @@ +{ "f1": 15345, "f2": 15345, "f3": 15300, "f4": -20000, "f5": 0 } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round7_with_digit_int32/round6_with_digit_int16.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round7_with_digit_int32/round6_with_digit_int16.1.adm new file mode 100644 index 0000000..c94de4d --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round7_with_digit_int32/round6_with_digit_int16.1.adm @@ -0,0 +1 @@ +{ "f1": 2147483647, "f2": 2147483647, "f3": 2147483650, "f4": -2147480000, "f5": 2147500000, "f6": 0 } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round8_with_digit_int64/round8_with_digit_int64.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round8_with_digit_int64/round8_with_digit_int64.1.adm new file mode 100644 index 0000000..af70864 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round8_with_digit_int64/round8_with_digit_int64.1.adm @@ -0,0 +1 @@ +{ "f1": 9223372036854775807, "f2": 9223372036854775807, "f3": 123460, "f4": -9223372036854775808, "f5": 9223372036854775807, "f6": -9223372000000000000 } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round9_with_digit_float/round9_with_digit_float.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round9_with_digit_float/round9_with_digit_float.1.adm new file mode 100644 index 0000000..cb2517f --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/round9_with_digit_float/round9_with_digit_float.1.adm @@ -0,0 +1 @@ +{ "f1": 456.0, "f2": 456.46, "f3": 460.0, "f4": -500.0, "f5": 456.456, "f6": 0.0 } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml index 1d924e6..9d5d44f 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml @@ -7235,6 +7235,41 @@ </compilation-unit> </test-case> <test-case FilePath="numeric"> + <compilation-unit name="round5_with_digit_int8"> + <output-dir compare="Text">round5_with_digit_int8</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="numeric"> + <compilation-unit name="round6_with_digit_int16"> + <output-dir compare="Text">round6_with_digit_int16</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="numeric"> + <compilation-unit name="round7_with_digit_int32"> + <output-dir compare="Text">round7_with_digit_int32</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="numeric"> + <compilation-unit name="round8_with_digit_int64"> + <output-dir compare="Text">round8_with_digit_int64</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="numeric"> + <compilation-unit name="round9_with_digit_float"> + <output-dir compare="Text">round9_with_digit_float</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="numeric"> + <compilation-unit name="round10_with_digit_double"> + <output-dir compare="Text">round10_with_digit_double</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="numeric"> + <compilation-unit name="round11_invalid"> + <output-dir compare="Text">round11_invalid</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="numeric"> <compilation-unit name="subtract_double"> <output-dir compare="Text">subtract_double</output-dir> </compilation-unit> 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 8ab1894..43664fb 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 @@ -105,6 +105,7 @@ import org.apache.asterix.om.typecomputer.impl.NumericDoubleOutputFunctionTypeComputer; import org.apache.asterix.om.typecomputer.impl.NumericInt8OutputFunctionTypeComputer; import org.apache.asterix.om.typecomputer.impl.NumericRound2TypeComputer; +import org.apache.asterix.om.typecomputer.impl.NumericRoundFunctionTypeComputer; import org.apache.asterix.om.typecomputer.impl.NumericSumAggTypeComputer; import org.apache.asterix.om.typecomputer.impl.NumericUnaryFunctionTypeComputer; import org.apache.asterix.om.typecomputer.impl.OpenARecordTypeComputer; @@ -360,6 +361,8 @@ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "floor", 1); public static final FunctionIdentifier NUMERIC_ROUND = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "round", 1); + public static final FunctionIdentifier NUMERIC_ROUND_WITH_ROUND_DIGIT = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "round", 2); public static final FunctionIdentifier NUMERIC_ROUND_HALF_TO_EVEN = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "round-half-to-even", 1); public static final FunctionIdentifier NUMERIC_ROUND_HALF_TO_EVEN2 = @@ -1659,7 +1662,8 @@ addFunction(NUMERIC_SIGN, NumericInt8OutputFunctionTypeComputer.INSTANCE, true); addFunction(NUMERIC_CEILING, NumericUnaryFunctionTypeComputer.INSTANCE, true); addFunction(NUMERIC_FLOOR, NumericUnaryFunctionTypeComputer.INSTANCE, true); - addFunction(NUMERIC_ROUND, NumericUnaryFunctionTypeComputer.INSTANCE, true); + addFunction(NUMERIC_ROUND, NumericRoundFunctionTypeComputer.INSTANCE, true); + addFunction(NUMERIC_ROUND_WITH_ROUND_DIGIT, NumericRoundFunctionTypeComputer.INSTANCE, true); addFunction(NUMERIC_ROUND_HALF_TO_EVEN, NumericUnaryFunctionTypeComputer.INSTANCE, true); addFunction(NUMERIC_ROUND_HALF_TO_EVEN2, NumericRound2TypeComputer.INSTANCE, true); addFunction(NUMERIC_TRUNC, NumericRound2TypeComputer.INSTANCE, true); diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRoundFunctionTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRoundFunctionTypeComputer.java new file mode 100644 index 0000000..ffdb066 --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericRoundFunctionTypeComputer.java @@ -0,0 +1,92 @@ +/* + * 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. + */ +/* + * Numeric Unary Functions like abs + * Author : Xiaoyu Ma@UC Irvine + * 01/30/2012 + */ +package org.apache.asterix.om.typecomputer.impl; + +import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.asterix.om.types.AUnionType; +import org.apache.asterix.om.types.BuiltinType; +import org.apache.asterix.om.types.IAType; +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; + +/** + * Type computer for round function. This type computer receives 1 or 2 arguments. The 1st argument is the value to + * round, and the 2nd argument (optional) is the digit to round to. The behavior of the type computer is as follows: + * + * - For integer types, the return type is int64. + * - For float type, the return type is float. + * - For double type, the return type is double. + * - For any type, the return type is any. + * - For all other types, the return type is null. + */ + +public class NumericRoundFunctionTypeComputer extends AbstractResultTypeComputer { + public static final NumericRoundFunctionTypeComputer INSTANCE = new NumericRoundFunctionTypeComputer(); + + private NumericRoundFunctionTypeComputer() { + } + + @Override + protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { + IAType returnType; + ATypeTag firstArgType = strippedInputTypes[0].getTypeTag(); + ATypeTag secondArgType = strippedInputTypes.length > 1 ? strippedInputTypes[1].getTypeTag() : null; + + switch (firstArgType) { + case TINYINT: + case SMALLINT: + case INTEGER: + case BIGINT: + returnType = BuiltinType.AINT64; + break; + case FLOAT: + case DOUBLE: + case ANY: + returnType = strippedInputTypes[0]; + break; + default: + return BuiltinType.ANULL; + } + + // No second argument + if (secondArgType == null) { + return returnType; + } + + switch (secondArgType) { + case TINYINT: + case SMALLINT: + case INTEGER: + case BIGINT: + case ANY: + return returnType; + case FLOAT: + case DOUBLE: + return AUnionType.createNullableType(returnType); + default: + return BuiltinType.ANULL; + } + } +} diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundDescriptor.java index 9b0dd20..5158463 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundDescriptor.java @@ -23,49 +23,20 @@ */ package org.apache.asterix.runtime.evaluators.functions; -import java.io.DataOutput; - import org.apache.asterix.common.annotations.MissingNullInOutFunction; -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.formats.nontagged.SerializerDeserializerProvider; -import org.apache.asterix.om.base.AMutableDouble; -import org.apache.asterix.om.base.AMutableFloat; -import org.apache.asterix.om.base.AMutableInt16; -import org.apache.asterix.om.base.AMutableInt32; -import org.apache.asterix.om.base.AMutableInt64; -import org.apache.asterix.om.base.AMutableInt8; 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.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.VoidPointable; -import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; -import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference; @MissingNullInOutFunction public class NumericRoundDescriptor extends AbstractScalarFunctionDynamicDescriptor { private static final long serialVersionUID = 1L; - public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { - @Override - public IFunctionDescriptor createFunctionDescriptor() { - return new NumericRoundDescriptor(); - } - }; + public static final IFunctionDescriptorFactory FACTORY = NumericRoundDescriptor::new; @Override public FunctionIdentifier getIdentifier() { @@ -79,82 +50,7 @@ @Override public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException { - - return new IScalarEvaluator() { - - private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); - private DataOutput out = resultStorage.getDataOutput(); - private IPointable argPtr = new VoidPointable(); - private IScalarEvaluator eval = args[0].createScalarEvaluator(ctx); - private AMutableDouble aDouble = new AMutableDouble(0); - private AMutableFloat aFloat = new AMutableFloat(0); - private AMutableInt64 aInt64 = new AMutableInt64(0); - private AMutableInt32 aInt32 = new AMutableInt32(0); - private AMutableInt16 aInt16 = new AMutableInt16((short) 0); - private AMutableInt8 aInt8 = new AMutableInt8((byte) 0); - @SuppressWarnings("rawtypes") - private ISerializerDeserializer serde; - - @SuppressWarnings("unchecked") - @Override - public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException { - resultStorage.reset(); - eval.evaluate(tuple, argPtr); - - if (PointableHelper.checkAndSetMissingOrNull(result, argPtr)) { - return; - } - - byte[] data = argPtr.getByteArray(); - int offset = argPtr.getStartOffset(); - - if (data[offset] == ATypeTag.SERIALIZED_INT8_TYPE_TAG) { - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.AINT8); - byte val = AInt8SerializerDeserializer.getByte(data, offset + 1); - aInt8.setValue(val); - serde.serialize(aInt8, out); - } else if (data[offset] == ATypeTag.SERIALIZED_INT16_TYPE_TAG) { - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.AINT16); - short val = AInt16SerializerDeserializer.getShort(data, offset + 1); - aInt16.setValue(val); - serde.serialize(aInt16, out); - } else if (data[offset] == ATypeTag.SERIALIZED_INT32_TYPE_TAG) { - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.AINT32); - int val = AInt32SerializerDeserializer.getInt(data, offset + 1); - aInt32.setValue(val); - serde.serialize(aInt32, out); - } else if (data[offset] == ATypeTag.SERIALIZED_INT64_TYPE_TAG) { - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.AINT64); - long val = AInt64SerializerDeserializer.getLong(data, offset + 1); - aInt64.setValue(val); - serde.serialize(aInt64, out); - } else if (data[offset] == ATypeTag.SERIALIZED_FLOAT_TYPE_TAG) { - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.AFLOAT); - float val = AFloatSerializerDeserializer.getFloat(data, offset + 1); - val = Math.round(val); - aFloat.setValue(val); - serde.serialize(aFloat, out); - } else if (data[offset] == ATypeTag.SERIALIZED_DOUBLE_TYPE_TAG) { - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ADOUBLE); - double val = ADoubleSerializerDeserializer.getDouble(data, offset + 1); - val = Math.round(val); - aDouble.setValue(val); - serde.serialize(aDouble, out); - } else { - throw new TypeMismatchException(sourceLoc, getIdentifier(), 0, data[offset], - ATypeTag.SERIALIZED_INT8_TYPE_TAG, ATypeTag.SERIALIZED_INT16_TYPE_TAG, - ATypeTag.SERIALIZED_INT32_TYPE_TAG, ATypeTag.SERIALIZED_INT64_TYPE_TAG, - ATypeTag.SERIALIZED_FLOAT_TYPE_TAG, ATypeTag.SERIALIZED_DOUBLE_TYPE_TAG); - } - result.set(resultStorage); - } - }; + return new NumericRoundEvaluator(ctx, args, getIdentifier(), sourceLoc); } }; } diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundEvaluator.java new file mode 100644 index 0000000..c06fd35 --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundEvaluator.java @@ -0,0 +1,255 @@ +/* + * 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.formats.nontagged.SerializerDeserializerProvider; +import org.apache.asterix.om.base.AMutableDouble; +import org.apache.asterix.om.base.AMutableFloat; +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.om.types.EnumDeserializer; +import org.apache.asterix.om.types.hierachy.ATypeHierarchy; +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.api.exceptions.SourceLocation; +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; + +/** + * This function rounds the numeric values. It receives 2 arguments, first is the numeric value to be rounded, second + * is an optional parameter to specify what digit to round to. If the provided rounding digit is positive, then the + * rounding should be at digits to the right of the decimal point, and if the rounding digit is negative, then the + * rounding should be at digits to the left of the decimal point. + * + * The return type behavior is as follows: + * int8, int16, int32 and int64 -> int64 is returned + * float -> float is returned + * double -> double is returned + * others -> null is returned + * + * Below is the formula used for rounding in the possible cases: + * + * Case 1: rounding digit is not provided or 0 + * - Normal Math.round(123.5) -> 124 + * + * Case 2: rounding digit is positive + * - multiplier = 10 ^ digit + * - Math.round(value * multiplier) / multiplier + * Example: + * - round(1.456, 2) + * - multiplier = 10 ^ 2 = 100 + * - value = value * multiplier = 1.456 * 100 = 145.6 + * - value = Math.round(value) = Math.round(145.6) = 146 + * - value = value / multiplier = 146 / 100 = 1.46 <--- final result + * + * Case 3: rounding digit is negative + * - multiplier = 10 ^ Math.abs(digit) + * - Math.round(value / multiplier) * multiplier + * Example: + * - round(1255, -2) + * - multiplier = 10 ^ Math.abs(-2) = 100 + * - value = value / multiplier = 1255 / 100 = 12.55 + * - value = Math.round(value) = Math.around(12.55) = 13 + * - value = value * multiplier = 13 * 100 = 1300 <--- final result + * + * Important: + * When dealing with big round decimal points, there is a potential of precision loss. + */ + +class NumericRoundEvaluator extends AbstractScalarEval { + + // Result members + private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); + private AMutableInt64 aInt64 = new AMutableInt64(0); + private AMutableFloat aFloat = new AMutableFloat(0); + private AMutableDouble aDouble = new AMutableDouble(0); + + // Evaluators and Pointables + private final IScalarEvaluator valueEvaluator; + private IScalarEvaluator roundingDigitEvaluator; + private final IPointable valuePointable; + private IPointable roundingDigitPointable; + + // Serializers/Deserializers + @SuppressWarnings("rawtypes") + protected ISerializerDeserializer int64Serde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64); + @SuppressWarnings("rawtypes") + protected ISerializerDeserializer floatSerde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AFLOAT); + @SuppressWarnings("rawtypes") + protected ISerializerDeserializer doubleSerde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADOUBLE); + + NumericRoundEvaluator(IHyracksTaskContext context, IScalarEvaluatorFactory[] argEvaluatorFactories, + FunctionIdentifier functionIdentifier, SourceLocation sourceLocation) throws HyracksDataException { + super(sourceLocation, functionIdentifier); + + valueEvaluator = argEvaluatorFactories[0].createScalarEvaluator(context); + valuePointable = new VoidPointable(); + + // 2nd argument if it exists + if (argEvaluatorFactories.length > 1) { + roundingDigitEvaluator = argEvaluatorFactories[1].createScalarEvaluator(context); + roundingDigitPointable = new VoidPointable(); + } + } + + @SuppressWarnings("unchecked") + @Override + public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException { + resultStorage.reset(); + valueEvaluator.evaluate(tuple, valuePointable); + + if (roundingDigitEvaluator != null) { + roundingDigitEvaluator.evaluate(tuple, roundingDigitPointable); + } + + if (PointableHelper.checkAndSetMissingOrNull(result, valuePointable, roundingDigitPointable)) { + return; + } + + byte[] valueBytes = valuePointable.getByteArray(); + int valueOffset = valuePointable.getStartOffset(); + ATypeTag valueTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(valueBytes[valueOffset]); + + byte[] roundingDigitBytes = null; + int roundingDigitOffset = 0; + + if (roundingDigitEvaluator != null) { + roundingDigitBytes = roundingDigitPointable.getByteArray(); + roundingDigitOffset = roundingDigitPointable.getStartOffset(); + } + + // Validity of arguments + if (!ATypeHierarchy.canPromote(valueTypeTag, ATypeTag.DOUBLE)) { + PointableHelper.setNull(result); + return; + } + + // Validity of arguments + if (roundingDigitEvaluator != null + && !PointableHelper.isValidLongValue(roundingDigitBytes, roundingDigitOffset, true)) { + PointableHelper.setNull(result); + return; + } + + // If we don't have the second argument, then rounding digit is 0, otherwise, read it from argument + long roundingDigit = roundingDigitEvaluator == null ? 0 + : ATypeHierarchy.getLongValue(functionIdentifier.getName(), 2, roundingDigitBytes, roundingDigitOffset); + + // Right of decimal + if (roundingDigit >= 0) { + + // Multiplier based on round digit + double multiplier = Math.pow(10, Math.abs(roundingDigit)); + + switch (valueTypeTag) { + // For zero and positive digit rounding, no need to do anything for integers + case TINYINT: + aInt64.setValue(AInt8SerializerDeserializer.getByte(valueBytes, valueOffset + 1)); + int64Serde.serialize(aInt64, resultStorage.getDataOutput()); + break; + case SMALLINT: + aInt64.setValue(AInt16SerializerDeserializer.getShort(valueBytes, valueOffset + 1)); + int64Serde.serialize(aInt64, resultStorage.getDataOutput()); + break; + case INTEGER: + aInt64.setValue(AInt32SerializerDeserializer.getInt(valueBytes, valueOffset + 1)); + int64Serde.serialize(aInt64, resultStorage.getDataOutput()); + break; + case BIGINT: + resultStorage.set(valuePointable); + break; + case FLOAT: + float floatValue = AFloatSerializerDeserializer.getFloat(valueBytes, valueOffset + 1); + // Maintain float precision in next operation + aFloat.setValue(Math.round(floatValue * (float) multiplier) / (float) multiplier); + floatSerde.serialize(aFloat, resultStorage.getDataOutput()); + break; + case DOUBLE: + double doubleValue = ADoubleSerializerDeserializer.getDouble(valueBytes, valueOffset + 1); + aDouble.setValue(Math.round(doubleValue * multiplier) / multiplier); + doubleSerde.serialize(aDouble, resultStorage.getDataOutput()); + break; + default: + PointableHelper.setNull(result); + return; + } + } + // Left of decimal (negative roundingDigit value) + else { + // Multiplier based on round digit + double multiplier = Math.pow(10, Math.abs(roundingDigit)); + + switch (valueTypeTag) { + case TINYINT: + byte byteValue = AInt8SerializerDeserializer.getByte(valueBytes, valueOffset + 1); + aInt64.setValue((long) (Math.round(byteValue / multiplier) * multiplier)); + int64Serde.serialize(aInt64, resultStorage.getDataOutput()); + break; + case SMALLINT: + short shortValue = AInt16SerializerDeserializer.getShort(valueBytes, valueOffset + 1); + aInt64.setValue((long) (Math.round(shortValue / multiplier) * multiplier)); + int64Serde.serialize(aInt64, resultStorage.getDataOutput()); + break; + case INTEGER: + int intValue = AInt32SerializerDeserializer.getInt(valueBytes, valueOffset + 1); + aInt64.setValue((long) (Math.round(intValue / multiplier) * multiplier)); + int64Serde.serialize(aInt64, resultStorage.getDataOutput()); + break; + case BIGINT: + long longValue = AInt64SerializerDeserializer.getLong(valueBytes, valueOffset + 1); + aInt64.setValue((long) (Math.round(longValue / multiplier) * multiplier)); + int64Serde.serialize(aInt64, resultStorage.getDataOutput()); + break; + case FLOAT: + float floatValue = AFloatSerializerDeserializer.getFloat(valueBytes, valueOffset + 1); + // Maintain float precision in next operation + aFloat.setValue(Math.round(floatValue / (float) multiplier) * (float) multiplier); + floatSerde.serialize(aFloat, resultStorage.getDataOutput()); + break; + case DOUBLE: + double doubleValue = ADoubleSerializerDeserializer.getDouble(valueBytes, valueOffset + 1); + aDouble.setValue(Math.round(doubleValue / multiplier) * multiplier); + doubleSerde.serialize(aDouble, resultStorage.getDataOutput()); + break; + default: + PointableHelper.setNull(result); + return; + } + } + + result.set(resultStorage); + } +} diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundWithRoundDigitDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundWithRoundDigitDescriptor.java new file mode 100644 index 0000000..a960922 --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericRoundWithRoundDigitDescriptor.java @@ -0,0 +1,59 @@ +/* + * 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. + */ +/* + * Numeric function Round + * Author : Xiaoyu Ma@UC Irvine + * 01/30/2012 + */ +package org.apache.asterix.runtime.evaluators.functions; + +import org.apache.asterix.common.annotations.MissingNullInOutFunction; +import org.apache.asterix.om.functions.BuiltinFunctions; +import org.apache.asterix.om.functions.IFunctionDescriptorFactory; +import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; +import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; +import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; +import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; +import org.apache.hyracks.api.context.IHyracksTaskContext; +import org.apache.hyracks.api.exceptions.HyracksDataException; + +@MissingNullInOutFunction +public class NumericRoundWithRoundDigitDescriptor extends AbstractScalarFunctionDynamicDescriptor { + + private static final long serialVersionUID = 1L; + public static final IFunctionDescriptorFactory FACTORY = NumericRoundWithRoundDigitDescriptor::new; + + @Override + public FunctionIdentifier getIdentifier() { + return BuiltinFunctions.NUMERIC_ROUND_WITH_ROUND_DIGIT; + } + + @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 NumericRoundEvaluator(ctx, args, getIdentifier(), sourceLoc); + } + }; + } + +} diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java index acc16e1..b5b2097 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java @@ -377,6 +377,7 @@ import org.apache.asterix.runtime.evaluators.functions.NumericRoundDescriptor; import org.apache.asterix.runtime.evaluators.functions.NumericRoundHalfToEven2Descriptor; import org.apache.asterix.runtime.evaluators.functions.NumericRoundHalfToEvenDescriptor; +import org.apache.asterix.runtime.evaluators.functions.NumericRoundWithRoundDigitDescriptor; import org.apache.asterix.runtime.evaluators.functions.NumericSignDescriptor; import org.apache.asterix.runtime.evaluators.functions.NumericSinDescriptor; import org.apache.asterix.runtime.evaluators.functions.NumericSinhDescriptor; @@ -893,6 +894,7 @@ fc.add(NumericCeilingDescriptor.FACTORY); fc.add(NumericFloorDescriptor.FACTORY); fc.add(NumericRoundDescriptor.FACTORY); + fc.add(NumericRoundWithRoundDigitDescriptor.FACTORY); fc.add(NumericRoundHalfToEvenDescriptor.FACTORY); fc.add(NumericRoundHalfToEven2Descriptor.FACTORY); fc.add(NumericACosDescriptor.FACTORY); -- To view, visit https://asterix-gerrit.ics.uci.edu/3433 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-MessageType: merged Gerrit-Change-Id: Ibdde2745e8bc440556e45ed07262eb33327f842b Gerrit-Change-Number: 3433 Gerrit-PatchSet: 10 Gerrit-Owner: Hussain Towaileb <hussai...@gmail.com> Gerrit-Reviewer: Ali Alsuliman <ali.al.solai...@gmail.com> Gerrit-Reviewer: Anon. E. Moose (1000171) Gerrit-Reviewer: Dmitry Lychagin <dmitry.lycha...@couchbase.com> Gerrit-Reviewer: Hussain Towaileb <hussai...@gmail.com> Gerrit-Reviewer: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Gerrit-Reviewer: Till Westmann <ti...@apache.org>