Dmitry Lychagin has submitted this change and it was merged. Change subject: [ASTERIXDB-2378][SQL] Add “DIV”, “MOD”, change “/“ for integers ......................................................................
[ASTERIXDB-2378][SQL] Add “DIV”, “MOD”, change “/“ for integers - user model changes: yes - storage format changes: no - interface changes: no Details: - Make "/" operator return double if both operands are integers - Add "DIV" operator which is the same as "/" except that it returns integer if both operands are integers (as "/" did before this change) - Add "MOD" operator which is an alias for "%" operator - Remove "IDIV" operator from the grammar Change-Id: I7c6b0704ce60a03dd3c10e1c75cb9761acc56536 Reviewed-on: https://asterix-gerrit.ics.uci.edu/2630 Tested-by: Jenkins <[email protected]> Contrib: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> Reviewed-by: Dmitry Lychagin <[email protected]> --- M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java A asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int16/divide_int16.2.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int32/divide_int32.2.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int64/divide_int64.2.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int8/divide_int8.2.query.aql M asterixdb/asterix-app/src/test/resources/runtimets/queries/string/substr01/substr01.3.query.aql A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int16/divide_int16.2.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int32/divide_int32.2.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int64/divide_int64.2.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int8/divide_int8.2.query.sqlpp M asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/substr01/substr01.3.query.sqlpp M asterixdb/asterix-app/src/test/resources/runtimets/results/custord/customer_q_04/customer_q_04.1.adm M asterixdb/asterix-app/src/test/resources/runtimets/results/custord/customer_q_05/customer_q_05.1.adm M asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int16/divide_int16.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int16/divide_int16.2.adm M asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int32/divide_int32.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int32/divide_int32.2.adm M asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int64/divide_int64.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int64/divide_int64.2.adm M asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int8/divide_int8.1.adm A asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int8/divide_int8.2.adm A asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int16/divide_int16.2.ast A asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int32/divide_int32.2.ast A asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int64/divide_int64.2.ast A asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int8/divide_int8.2.ast M asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/string/substr01/substr01.3.ast M asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md M asterixdb/asterix-doc/src/site/markdown/aql/manual.md M asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj M asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java M asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/OperatorType.java M asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java M asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj 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/NumericDivideTypeComputer.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java C asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivDescriptor.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java R asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericPowerDescriptor.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java 41 files changed, 1,071 insertions(+), 202 deletions(-) Approvals: Anon. E. Moose #1000171: Jenkins: Verified; ; Verified Dmitry Lychagin: Looks good to me, approved Objections: Jenkins: Violations found diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java index 4f9b4df..1a4f1c0 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java @@ -96,7 +96,7 @@ BuiltinFunctions.CREATE_POLYGON, BuiltinFunctions.CREATE_MBR, BuiltinFunctions.CREATE_RECTANGLE, BuiltinFunctions.CREATE_CIRCLE, BuiltinFunctions.CREATE_LINE, BuiltinFunctions.CREATE_POINT, BuiltinFunctions.NUMERIC_ADD, BuiltinFunctions.NUMERIC_SUBTRACT, BuiltinFunctions.NUMERIC_MULTIPLY, - BuiltinFunctions.NUMERIC_DIVIDE, BuiltinFunctions.NUMERIC_MOD); + BuiltinFunctions.NUMERIC_DIVIDE, BuiltinFunctions.NUMERIC_DIV, BuiltinFunctions.NUMERIC_MOD); public abstract Map<FunctionIdentifier, List<IAccessMethod>> getAccessMethods(); diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java index 6ab76fa..9a6870d 100644 --- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java +++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/LangExpressionToPlanTranslator.java @@ -42,7 +42,6 @@ import org.apache.asterix.lang.common.base.Expression; import org.apache.asterix.lang.common.base.Expression.Kind; import org.apache.asterix.lang.common.base.ILangExpression; -import org.apache.asterix.lang.common.base.Statement; import org.apache.asterix.lang.common.clause.GroupbyClause; import org.apache.asterix.lang.common.clause.LetClause; import org.apache.asterix.lang.common.clause.LimitClause; @@ -1261,17 +1260,17 @@ case MUL: fid = BuiltinFunctions.NUMERIC_MULTIPLY; break; - case DIV: + case DIVIDE: fid = BuiltinFunctions.NUMERIC_DIVIDE; + break; + case DIV: + fid = BuiltinFunctions.NUMERIC_DIV; break; case MOD: fid = BuiltinFunctions.NUMERIC_MOD; break; - case IDIV: - fid = BuiltinFunctions.NUMERIC_IDIV; - break; case CARET: - fid = BuiltinFunctions.CARET; + fid = BuiltinFunctions.NUMERIC_POWER; break; case AND: fid = AlgebricksBuiltinFunctions.AND; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int16/divide_int16.2.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int16/divide_int16.2.query.aql new file mode 100644 index 0000000..b59be3b --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int16/divide_int16.2.query.aql @@ -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. + */ + +let $c1 := int8("+1") +let $c2 := int16("2") +let $c3 := int32("+3") +let $c4 := int64("-4") +let $c5 := float("-5.5f") +let $c6 := double("-6.5d") +let $c8 := null +return {"result1": $c2 div $c1,"result2": $c2 div $c2,"result3": $c2 div $c3,"result4": $c2 div $c4,"result5": $c2 div $c5, "result6": $c2 div $c6, "result7": $c6 div $c8, "result8": $c6 div [1][1]} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int32/divide_int32.2.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int32/divide_int32.2.query.aql new file mode 100644 index 0000000..d8ad04a --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int32/divide_int32.2.query.aql @@ -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. + */ + +let $c1 := int8("+1") +let $c2 := int16("2") +let $c3 := int32("+3") +let $c4 := int64("-4") +let $c5 := float("-5.5f") +let $c6 := double("-6.5d") +let $c8 := null +return {"result1": $c3 div $c1,"result2": $c3 div $c2,"result3": $c3 div $c3,"result4": $c3 div $c4,"result5": $c3 div $c5, "result6": $c3 div $c6, "result7": $c6 div $c8, "result8": $c6 div [1][1]} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int64/divide_int64.2.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int64/divide_int64.2.query.aql new file mode 100644 index 0000000..32c72ed --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int64/divide_int64.2.query.aql @@ -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. + */ + +let $c1 := int8("+1") +let $c2 := int16("2") +let $c3 := int32("+3") +let $c4 := int64("-4") +let $c5 := float("-5.5f") +let $c6 := double("-6.5d") +let $c8 := null +return {"result1": $c4 div $c1,"result2": $c4 div $c2,"result3": $c4 div $c3,"result4": $c4 div $c4,"result5": $c4 div $c5, "result6": $c4 div $c6, "result7": $c6 div $c8, "result8": $c6 div [1][1]} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int8/divide_int8.2.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int8/divide_int8.2.query.aql new file mode 100644 index 0000000..5adb1b4 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/numeric/divide_int8/divide_int8.2.query.aql @@ -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. + */ + +let $c1 := int8("+1") +let $c2 := int16("2") +let $c3 := int32("+3") +let $c4 := int64("-4") +let $c5 := float("-5.5f") +let $c6 := double("-6.5d") +let $c8 := null +return {"result1": $c1 div $c1,"result2": $c1 div $c2,"result3": $c1 div $c3,"result4": $c1 div $c4,"result5": $c1 div $c5, "result6": $c1 div $c6, "result7": $c6 div $c8, "result8": $c6 div [1][1]} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/string/substr01/substr01.3.query.aql b/asterixdb/asterix-app/src/test/resources/runtimets/queries/string/substr01/substr01.3.query.aql index a45b24c..0ab61e8 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/string/substr01/substr01.3.query.aql +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/string/substr01/substr01.3.query.aql @@ -42,5 +42,5 @@ let $str12:="This is a another test string" let $str13:=substring(string-concat([$str11,$str12]),20) -let $str14:=substring("UC Irvine",string-length("UC Irvine")/2 - 1) +let $str14:=substring("UC Irvine",string-length("UC Irvine") div 2 - 1) return { "str2":$str2,"str4":$str4,"str6":$str6,"str8":$str8,"str10":$str10,"str13":$str13,"str14":$str14} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int16/divide_int16.2.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int16/divide_int16.2.query.sqlpp new file mode 100644 index 0000000..cca3dcf --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int16/divide_int16.2.query.sqlpp @@ -0,0 +1,20 @@ +/* + * 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. + */ + +{'result1':(smallint('2') div tinyint('+1')),'result2':(smallint('2') div smallint('2')),'result3':(smallint('2') div integer('+3')),'result4':(smallint('2') div bigint('-4')),'result5':(smallint('2') div float('-5.5f')),'result6':(smallint('2') div double('-6.5d')),'result7':(double('-6.5d') div null), 'result8':double('-6.5d') div {}.a}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int32/divide_int32.2.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int32/divide_int32.2.query.sqlpp new file mode 100644 index 0000000..7ce0f9e --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int32/divide_int32.2.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. + */ + + +{'result1':(integer('+3') div tinyint('+1')),'result2':(integer('+3') div smallint('2')),'result3':(integer('+3') div integer('+3')),'result4':(integer('+3') div bigint('-4')),'result5':(integer('+3') div float('-5.5f')),'result6':(integer('+3') div double('-6.5d')),'result7':(double('-6.5d') div null), 'result8':double('-6.5d') div {}.a}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int64/divide_int64.2.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int64/divide_int64.2.query.sqlpp new file mode 100644 index 0000000..2f850c2 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int64/divide_int64.2.query.sqlpp @@ -0,0 +1,20 @@ +/* + * 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. + */ + +{'result1':(bigint('-4') div tinyint('+1')),'result2':(bigint('-4') div smallint('2')),'result3':(bigint('-4') div integer('+3')),'result4':(bigint('-4') div bigint('-4')),'result5':(bigint('-4') div float('-5.5f')),'result6':(bigint('-4') div double('-6.5d')),'result7':(double('-6.5d') div null), 'result8':double('-6.5d') div {}.a}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int8/divide_int8.2.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int8/divide_int8.2.query.sqlpp new file mode 100644 index 0000000..5cf4b1b --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/numeric/divide_int8/divide_int8.2.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. + */ + + +{'result1':(tinyint('+1') div tinyint('+1')),'result2':(tinyint('+1') div smallint('2')),'result3':(tinyint('+1') div integer('+3')),'result4':(tinyint('+1') div bigint('-4')),'result5':(tinyint('+1') div float('-5.5f')),'result6':(tinyint('+1') div double('-6.5d')),'result7':(double('-6.5d') div null), 'result8':double('-6.5d') div {}.a}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/substr01/substr01.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/substr01/substr01.3.query.sqlpp index 6abe9ff..d39e51e 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/substr01/substr01.3.query.sqlpp +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/string/substr01/substr01.3.query.sqlpp @@ -23,4 +23,4 @@ * Date : 18th April 2012 */ -{'str2':substring('Hello World',9),'str4':substring('This is a test string',20),'str6':substring('This is a test string',21),'str8':substring('This is a test string',0),'str10':substring('This is a test string',-6),'str13':substring(`string-concat`(['This is a test string','This is a another test string']),20),'str14':substring('UC Irvine',(`string-length`('UC Irvine') / 2 - 1))}; +{'str2':substring('Hello World',9),'str4':substring('This is a test string',20),'str6':substring('This is a test string',21),'str8':substring('This is a test string',0),'str10':substring('This is a test string',-6),'str13':substring(`string-concat`(['This is a test string','This is a another test string']),20),'str14':substring('UC Irvine',(`string-length`('UC Irvine') div 2 - 1))}; diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/customer_q_04/customer_q_04.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/customer_q_04/customer_q_04.1.adm index 58d9bdc..dd41cbf 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/customer_q_04/customer_q_04.1.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/customer_q_04/customer_q_04.1.adm @@ -1,3 +1,3 @@ -{ "id": 775, "custname": "Jodi Rotruck", "age": null, "MathcashBack": { "cashBack": 100, "cashBack+5": 105, "cashBack-5": 95, "cashBack*5": 500, "cashBack/5": 20, "-cashBack": -100 } } -{ "id": 5, "custname": "Jodi Alex", "age": 19, "MathcashBack": { "cashBack": 350, "cashBack+5": 355, "cashBack-5": 345, "cashBack*5": 1750, "cashBack/5": 70, "-cashBack": -350 } } -{ "id": 4, "custname": "Mary Carey", "age": 12, "MathcashBack": { "cashBack": 450, "cashBack+5": 455, "cashBack-5": 445, "cashBack*5": 2250, "cashBack/5": 90, "-cashBack": -450 } } +{ "id": 775, "custname": "Jodi Rotruck", "age": null, "MathcashBack": { "cashBack": 100, "cashBack+5": 105, "cashBack-5": 95, "cashBack*5": 500, "cashBack/5": 20.0, "-cashBack": -100 } } +{ "id": 5, "custname": "Jodi Alex", "age": 19, "MathcashBack": { "cashBack": 350, "cashBack+5": 355, "cashBack-5": 345, "cashBack*5": 1750, "cashBack/5": 70.0, "-cashBack": -350 } } +{ "id": 4, "custname": "Mary Carey", "age": 12, "MathcashBack": { "cashBack": 450, "cashBack+5": 455, "cashBack-5": 445, "cashBack*5": 2250, "cashBack/5": 90.0, "-cashBack": -450 } } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/customer_q_05/customer_q_05.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/customer_q_05/customer_q_05.1.adm index 89f8083..2990e0e 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/customer_q_05/customer_q_05.1.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/custord/customer_q_05/customer_q_05.1.adm @@ -1,3 +1,3 @@ { "custname": "Jodi Rotruck", "age": null, "MathAge": { "age": null, "age+5": null, "age-5": null, "age*5": null, "age/5": null, "-age": null } } -{ "custname": "Jodi Alex", "age": 19, "MathAge": { "age": 19, "age+5": 24, "age-5": 14, "age*5": 95, "age/5": 3, "-age": -19 } } -{ "custname": "Mary Carey", "age": 12, "MathAge": { "age": 12, "age+5": 17, "age-5": 7, "age*5": 60, "age/5": 2, "-age": -12 } } +{ "custname": "Jodi Alex", "age": 19, "MathAge": { "age": 19, "age+5": 24, "age-5": 14, "age*5": 95, "age/5": 3.8, "-age": -19 } } +{ "custname": "Mary Carey", "age": 12, "MathAge": { "age": 12, "age+5": 17, "age-5": 7, "age*5": 60, "age/5": 2.4, "-age": -12 } } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int16/divide_int16.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int16/divide_int16.1.adm index 47c4e3c..775745b 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int16/divide_int16.1.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int16/divide_int16.1.adm @@ -1 +1 @@ -{ "result1": 2, "result2": 1, "result3": 0, "result4": 0, "result5": -0.36363637, "result6": -0.3076923076923077, "result7": null } +{ "result1": 2.0, "result2": 1.0, "result3": 0.6666666666666666, "result4": -0.5, "result5": -0.36363637, "result6": -0.3076923076923077, "result7": null } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int16/divide_int16.2.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int16/divide_int16.2.adm new file mode 100644 index 0000000..c3d22c3 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int16/divide_int16.2.adm @@ -0,0 +1 @@ +{ "result1": 2, "result2": 1, "result3": 0, "result4": 0, "result5": -0.36363637, "result6": -0.3076923076923077, "result7": null } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int32/divide_int32.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int32/divide_int32.1.adm index 83c2d70..890417b 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int32/divide_int32.1.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int32/divide_int32.1.adm @@ -1 +1 @@ -{ "result1": 3, "result2": 1, "result3": 1, "result4": 0, "result5": -0.54545456, "result6": -0.46153846153846156, "result7": null } +{ "result1": 3.0, "result2": 1.5, "result3": 1.0, "result4": -0.75, "result5": -0.54545456, "result6": -0.46153846153846156, "result7": null } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int32/divide_int32.2.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int32/divide_int32.2.adm new file mode 100644 index 0000000..788a291 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int32/divide_int32.2.adm @@ -0,0 +1 @@ +{ "result1": 3, "result2": 1, "result3": 1, "result4": 0, "result5": -0.54545456, "result6": -0.46153846153846156, "result7": null } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int64/divide_int64.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int64/divide_int64.1.adm index a6fea08..582b44d 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int64/divide_int64.1.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int64/divide_int64.1.adm @@ -1 +1 @@ -{ "result1": -4, "result2": -2, "result3": -1, "result4": 1, "result5": 0.72727275, "result6": 0.6153846153846154, "result7": null } +{ "result1": -4.0, "result2": -2.0, "result3": -1.3333333333333333, "result4": 1.0, "result5": 0.72727275, "result6": 0.6153846153846154, "result7": null } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int64/divide_int64.2.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int64/divide_int64.2.adm new file mode 100644 index 0000000..af75a4e --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int64/divide_int64.2.adm @@ -0,0 +1 @@ +{ "result1": -4, "result2": -2, "result3": -1, "result4": 1, "result5": 0.72727275, "result6": 0.6153846153846154, "result7": null } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int8/divide_int8.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int8/divide_int8.1.adm index 1def226..591ed6d 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int8/divide_int8.1.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int8/divide_int8.1.adm @@ -1 +1 @@ -{ "result1": 1, "result2": 0, "result3": 0, "result4": 0, "result5": -0.18181819, "result6": -0.15384615384615385, "result7": null } +{ "result1": 1.0, "result2": 0.5, "result3": 0.3333333333333333, "result4": -0.25, "result5": -0.18181819, "result6": -0.15384615384615385, "result7": null } diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int8/divide_int8.2.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int8/divide_int8.2.adm new file mode 100644 index 0000000..f232ecf --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/numeric/divide_int8/divide_int8.2.adm @@ -0,0 +1 @@ +{ "result1": 1, "result2": 0, "result3": 0, "result4": 0, "result5": -0.18181819, "result6": -0.15384615384615385, "result7": null } \ No newline at end of file diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int16/divide_int16.2.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int16/divide_int16.2.ast new file mode 100644 index 0000000..90fd039 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int16/divide_int16.2.ast @@ -0,0 +1,107 @@ +Query: +RecordConstructor [ + ( + LiteralExpr [STRING] [result1] + : + OperatorExpr [ + FunctionCall null.int16@1[ + LiteralExpr [STRING] [2] + ] + div + FunctionCall null.int8@1[ + LiteralExpr [STRING] [+1] + ] + ] + ) + ( + LiteralExpr [STRING] [result2] + : + OperatorExpr [ + FunctionCall null.int16@1[ + LiteralExpr [STRING] [2] + ] + div + FunctionCall null.int16@1[ + LiteralExpr [STRING] [2] + ] + ] + ) + ( + LiteralExpr [STRING] [result3] + : + OperatorExpr [ + FunctionCall null.int16@1[ + LiteralExpr [STRING] [2] + ] + div + FunctionCall null.int32@1[ + LiteralExpr [STRING] [+3] + ] + ] + ) + ( + LiteralExpr [STRING] [result4] + : + OperatorExpr [ + FunctionCall null.int16@1[ + LiteralExpr [STRING] [2] + ] + div + FunctionCall null.int64@1[ + LiteralExpr [STRING] [-4] + ] + ] + ) + ( + LiteralExpr [STRING] [result5] + : + OperatorExpr [ + FunctionCall null.int16@1[ + LiteralExpr [STRING] [2] + ] + div + FunctionCall null.float@1[ + LiteralExpr [STRING] [-5.5f] + ] + ] + ) + ( + LiteralExpr [STRING] [result6] + : + OperatorExpr [ + FunctionCall null.int16@1[ + LiteralExpr [STRING] [2] + ] + div + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + ] + ) + ( + LiteralExpr [STRING] [result7] + : + OperatorExpr [ + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + div + LiteralExpr [NULL] + ] + ) + ( + LiteralExpr [STRING] [result8] + : + OperatorExpr [ + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + div + FieldAccessor [ + RecordConstructor [ + ] + Field=a + ] + ] + ) +] diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int32/divide_int32.2.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int32/divide_int32.2.ast new file mode 100644 index 0000000..05bd4a7 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int32/divide_int32.2.ast @@ -0,0 +1,107 @@ +Query: +RecordConstructor [ + ( + LiteralExpr [STRING] [result1] + : + OperatorExpr [ + FunctionCall null.int32@1[ + LiteralExpr [STRING] [+3] + ] + div + FunctionCall null.int8@1[ + LiteralExpr [STRING] [+1] + ] + ] + ) + ( + LiteralExpr [STRING] [result2] + : + OperatorExpr [ + FunctionCall null.int32@1[ + LiteralExpr [STRING] [+3] + ] + div + FunctionCall null.int16@1[ + LiteralExpr [STRING] [2] + ] + ] + ) + ( + LiteralExpr [STRING] [result3] + : + OperatorExpr [ + FunctionCall null.int32@1[ + LiteralExpr [STRING] [+3] + ] + div + FunctionCall null.int32@1[ + LiteralExpr [STRING] [+3] + ] + ] + ) + ( + LiteralExpr [STRING] [result4] + : + OperatorExpr [ + FunctionCall null.int32@1[ + LiteralExpr [STRING] [+3] + ] + div + FunctionCall null.int64@1[ + LiteralExpr [STRING] [-4] + ] + ] + ) + ( + LiteralExpr [STRING] [result5] + : + OperatorExpr [ + FunctionCall null.int32@1[ + LiteralExpr [STRING] [+3] + ] + div + FunctionCall null.float@1[ + LiteralExpr [STRING] [-5.5f] + ] + ] + ) + ( + LiteralExpr [STRING] [result6] + : + OperatorExpr [ + FunctionCall null.int32@1[ + LiteralExpr [STRING] [+3] + ] + div + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + ] + ) + ( + LiteralExpr [STRING] [result7] + : + OperatorExpr [ + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + div + LiteralExpr [NULL] + ] + ) + ( + LiteralExpr [STRING] [result8] + : + OperatorExpr [ + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + div + FieldAccessor [ + RecordConstructor [ + ] + Field=a + ] + ] + ) +] diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int64/divide_int64.2.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int64/divide_int64.2.ast new file mode 100644 index 0000000..5e1007a --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int64/divide_int64.2.ast @@ -0,0 +1,107 @@ +Query: +RecordConstructor [ + ( + LiteralExpr [STRING] [result1] + : + OperatorExpr [ + FunctionCall null.int64@1[ + LiteralExpr [STRING] [-4] + ] + div + FunctionCall null.int8@1[ + LiteralExpr [STRING] [+1] + ] + ] + ) + ( + LiteralExpr [STRING] [result2] + : + OperatorExpr [ + FunctionCall null.int64@1[ + LiteralExpr [STRING] [-4] + ] + div + FunctionCall null.int16@1[ + LiteralExpr [STRING] [2] + ] + ] + ) + ( + LiteralExpr [STRING] [result3] + : + OperatorExpr [ + FunctionCall null.int64@1[ + LiteralExpr [STRING] [-4] + ] + div + FunctionCall null.int32@1[ + LiteralExpr [STRING] [+3] + ] + ] + ) + ( + LiteralExpr [STRING] [result4] + : + OperatorExpr [ + FunctionCall null.int64@1[ + LiteralExpr [STRING] [-4] + ] + div + FunctionCall null.int64@1[ + LiteralExpr [STRING] [-4] + ] + ] + ) + ( + LiteralExpr [STRING] [result5] + : + OperatorExpr [ + FunctionCall null.int64@1[ + LiteralExpr [STRING] [-4] + ] + div + FunctionCall null.float@1[ + LiteralExpr [STRING] [-5.5f] + ] + ] + ) + ( + LiteralExpr [STRING] [result6] + : + OperatorExpr [ + FunctionCall null.int64@1[ + LiteralExpr [STRING] [-4] + ] + div + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + ] + ) + ( + LiteralExpr [STRING] [result7] + : + OperatorExpr [ + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + div + LiteralExpr [NULL] + ] + ) + ( + LiteralExpr [STRING] [result8] + : + OperatorExpr [ + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + div + FieldAccessor [ + RecordConstructor [ + ] + Field=a + ] + ] + ) +] diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int8/divide_int8.2.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int8/divide_int8.2.ast new file mode 100644 index 0000000..6442d38 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/numeric/divide_int8/divide_int8.2.ast @@ -0,0 +1,107 @@ +Query: +RecordConstructor [ + ( + LiteralExpr [STRING] [result1] + : + OperatorExpr [ + FunctionCall null.int8@1[ + LiteralExpr [STRING] [+1] + ] + div + FunctionCall null.int8@1[ + LiteralExpr [STRING] [+1] + ] + ] + ) + ( + LiteralExpr [STRING] [result2] + : + OperatorExpr [ + FunctionCall null.int8@1[ + LiteralExpr [STRING] [+1] + ] + div + FunctionCall null.int16@1[ + LiteralExpr [STRING] [2] + ] + ] + ) + ( + LiteralExpr [STRING] [result3] + : + OperatorExpr [ + FunctionCall null.int8@1[ + LiteralExpr [STRING] [+1] + ] + div + FunctionCall null.int32@1[ + LiteralExpr [STRING] [+3] + ] + ] + ) + ( + LiteralExpr [STRING] [result4] + : + OperatorExpr [ + FunctionCall null.int8@1[ + LiteralExpr [STRING] [+1] + ] + div + FunctionCall null.int64@1[ + LiteralExpr [STRING] [-4] + ] + ] + ) + ( + LiteralExpr [STRING] [result5] + : + OperatorExpr [ + FunctionCall null.int8@1[ + LiteralExpr [STRING] [+1] + ] + div + FunctionCall null.float@1[ + LiteralExpr [STRING] [-5.5f] + ] + ] + ) + ( + LiteralExpr [STRING] [result6] + : + OperatorExpr [ + FunctionCall null.int8@1[ + LiteralExpr [STRING] [+1] + ] + div + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + ] + ) + ( + LiteralExpr [STRING] [result7] + : + OperatorExpr [ + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + div + LiteralExpr [NULL] + ] + ) + ( + LiteralExpr [STRING] [result8] + : + OperatorExpr [ + FunctionCall null.double@1[ + LiteralExpr [STRING] [-6.5d] + ] + div + FieldAccessor [ + RecordConstructor [ + ] + Field=a + ] + ] + ) +] diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/string/substr01/substr01.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/string/substr01/substr01.3.ast index 4b7138d..9d1c274 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/string/substr01/substr01.3.ast +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/string/substr01/substr01.3.ast @@ -63,7 +63,7 @@ FunctionCall null.string-length@1[ LiteralExpr [STRING] [UC Irvine] ] - / + div LiteralExpr [LONG] [2] ] - diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md index 6ac6db1..8d9b2fe 100644 --- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md +++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/2_expr.md @@ -49,9 +49,9 @@ |-----------------------------------------------------------------------------|-----------| | EXISTS, NOT EXISTS | Collection emptiness testing | | ^ | Exponentiation | -| *, /, % | Multiplication, division, modulo | +| *, /, DIV, MOD (%) | Multiplication, division, modulo | | +, - | Addition, subtraction | -| || | String concatenation | +| || | String concatenation | | IS NULL, IS NOT NULL, IS MISSING, IS NOT MISSING, <br/>IS UNKNOWN, IS NOT UNKNOWN, IS VALUED, IS NOT VALUED | Unknown value comparison | | BETWEEN, NOT BETWEEN | Range comparison (inclusive on both sides) | | =, !=, <>, <, >, <=, >=, LIKE, NOT LIKE, IN, NOT IN | Comparison | @@ -71,7 +71,10 @@ |--------------|-------------------------------------------------------------------------|------------| | +, - | As unary operators, they denote a <br/>positive or negative expression | SELECT VALUE -1; | | +, - | As binary operators, they add or subtract | SELECT VALUE 1 + 2; | -| *, /, % | Multiply, divide, modulo | SELECT VALUE 4 / 2.0; | +| * | Multiply | SELECT VALUE 4 * 2; | +| / | Divide (returns a value of type `double` if both operands are integers)| SELECT VALUE 5 / 2; | +| DIV | Divide (returns an integer value if both operands are integers) | SELECT VALUE 5 DIV 2; | +| MOD (%) | Modulo | SELECT VALUE 5 % 2; | | ^ | Exponentiation | SELECT VALUE 2^3; | | || | String concatenation | SELECT VALUE "ab"||"c"||"d"; | diff --git a/asterixdb/asterix-doc/src/site/markdown/aql/manual.md b/asterixdb/asterix-doc/src/site/markdown/aql/manual.md index 95c752f..43a7cd5 100644 --- a/asterixdb/asterix-doc/src/site/markdown/aql/manual.md +++ b/asterixdb/asterix-doc/src/site/markdown/aql/manual.md @@ -283,7 +283,7 @@ ### Arithmetic Expressions AddExpr ::= MultExpr ( ( "+" | "-" ) MultExpr )* - MultExpr ::= UnaryExpr ( ( "*" | "/" | "%" | "^"| "idiv" ) UnaryExpr )* + MultExpr ::= UnaryExpr ( ( "*" | "/" | "div" | "%" | "mod" | "^" ) UnaryExpr )* UnaryExpr ::= ( ( "+" | "-" ) )? ValueExpr AQL also supports the usual cast of characters for arithmetic expressions. diff --git a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj index 2d87556..856073d 100644 --- a/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj +++ b/asterixdb/asterix-lang-aql/src/main/javacc/AQL.jj @@ -147,6 +147,7 @@ import org.apache.asterix.lang.common.statement.UpsertStatement; import org.apache.asterix.lang.common.statement.WriteStatement; import org.apache.asterix.lang.common.struct.Identifier; +import org.apache.asterix.lang.common.struct.OperatorType; import org.apache.asterix.lang.common.struct.QuantifiedPair; import org.apache.asterix.lang.common.struct.VarIdentifier; import org.apache.asterix.metadata.utils.MetadataConstants; @@ -1811,23 +1812,25 @@ Expression MultExpr()throws ParseException: { OperatorExpr op = null; + OperatorType opType = null; Expression operand = null; } { operand = ExponentExpr() - (( <MUL> | <DIV> | <MOD> | <IDIV>) + ( ( + <MUL> { opType = OperatorType.MUL; } | + <DIVIDE> { opType = OperatorType.DIVIDE; } | + <DIV> { opType = OperatorType.DIV; } | + ( <MOD> | <PERCENT> ) { opType = OperatorType.MOD; } + ) { if (op == null) { op = new OperatorExpr(); op.addOperand(operand); op.setCurrentop(true); } - try{ - op.addOperator(token.image); - } catch (CompilationException e){ - throw new ParseException(e.getMessage()); - } + op.addOperator(opType); } operand = ExponentExpr() { @@ -2724,10 +2727,10 @@ TOKEN : { <CARET : "^"> - | <DIV : "/"> - | <IDIV : "idiv"> + | <DIVIDE : "/"> + | <DIV : "div"> | <MINUS : "-"> - | <MOD : "%"> + | <MOD : "mod"> | <MUL : "*"> | <PLUS : "+"> @@ -2739,6 +2742,7 @@ | <COLON : ":"> | <COMMA : ","> | <DOT : "."> + | <PERCENT: "%"> | <QUES : "?"> | <LT : "<"> diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java index 90b457e..9521469 100644 --- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java +++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java @@ -84,10 +84,18 @@ exprList.add(operand); } - public static final boolean opIsComparison(OperatorType t) { - boolean cmp = t == OperatorType.EQ || t == OperatorType.NEQ || t == OperatorType.GT; - cmp = cmp || t == OperatorType.GE || t == OperatorType.LT || t == OperatorType.LE; - return cmp; + public static boolean opIsComparison(OperatorType t) { + switch (t) { + case EQ: + case NEQ: + case GT: + case GE: + case LT: + case LE: + return true; + default: + return false; + } } public void addOperator(String strOp) throws CompilationException { diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/OperatorType.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/OperatorType.java index e11f169..f4f2ae1 100644 --- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/OperatorType.java +++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/OperatorType.java @@ -31,11 +31,10 @@ MINUS("-"), CONCAT("||"), MUL("*"), - DIV("/"), // float/double - // divide - MOD("%"), + DIVIDE("/"), + DIV("div"), + MOD("mod"), CARET("^"), - IDIV("idiv"), // integer divide FUZZY_EQ("~="), LIKE("like"), NOT_LIKE("not_like"), 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 332fd2f..83dc2f1b 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 @@ -39,7 +39,6 @@ addFunctionMapping("upper", "uppercase"); // upper, internal: uppercase addFunctionMapping("title", "initcap"); // title, internal: initcap addFunctionMapping("regexp_contains", "matches"); // regexp_contains, internal: matches - addFunctionMapping("power", "caret"); //pow, internal: caret addFunctionMapping("int", "integer"); // int, internal: integer // The "mapped-to" names are to be deprecated. diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj index 56c98bb..c3a9c0b 100644 --- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj +++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj @@ -2143,23 +2143,25 @@ Expression MultExpr()throws ParseException: { OperatorExpr op = null; + OperatorType opType = null; Expression operand = null; } { operand = ExponentExpr() - (( <MUL> | <DIV> | <MOD> | <IDIV>) + ( ( + <MUL> { opType = OperatorType.MUL; } | + <DIVIDE> { opType = OperatorType.DIVIDE; } | + <DIV> { opType = OperatorType.DIV; } | + ( <MOD> | <PERCENT> ) { opType = OperatorType.MOD; } + ) { if (op == null) { op = new OperatorExpr(); op.addOperand(operand); op.setCurrentop(true); } - try{ - op.addOperator(token.image); - } catch (Exception e){ - throw new ParseException(e.getMessage()); - } + op.addOperator(opType); } operand = ExponentExpr() { @@ -3311,10 +3313,10 @@ { <CARET : "^"> | <CONCAT : "||"> - | <DIV : "/"> - | <IDIV : "idiv"> + | <DIVIDE : "/"> + | <DIV : "div"> | <MINUS : "-"> - | <MOD : "%"> + | <MOD : "mod"> | <MUL : "*"> | <PLUS : "+"> @@ -3327,6 +3329,7 @@ | <COLON : ":"> | <COMMA : ","> | <DOT : "."> + | <PERCENT: "%"> | <QUES : "?"> | <SEMICOLON : ";"> | <SHARP : "#"> 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 222b539..c40d550 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 @@ -82,6 +82,7 @@ import org.apache.asterix.om.typecomputer.impl.NullableDoubleTypeComputer; import org.apache.asterix.om.typecomputer.impl.NumericAddSubMulDivTypeComputer; import org.apache.asterix.om.typecomputer.impl.NumericAggTypeComputer; +import org.apache.asterix.om.typecomputer.impl.NumericDivideTypeComputer; import org.apache.asterix.om.typecomputer.impl.NumericDoubleOutputFunctionTypeComputer; import org.apache.asterix.om.typecomputer.impl.NumericInt8OutputFunctionTypeComputer; import org.apache.asterix.om.typecomputer.impl.NumericRound2TypeComputer; @@ -231,9 +232,10 @@ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "numeric-divide", 2); public static final FunctionIdentifier NUMERIC_MOD = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "numeric-mod", 2); - public static final FunctionIdentifier NUMERIC_IDIV = - new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "numeric-idiv", 2); - public static final FunctionIdentifier CARET = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "caret", 2); + public static final FunctionIdentifier NUMERIC_DIV = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "numeric-div", 2); + public static final FunctionIdentifier NUMERIC_POWER = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "power", 2); public static final FunctionIdentifier NUMERIC_ABS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "abs", 1); public static final FunctionIdentifier NUMERIC_ACOS = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "acos", 1); @@ -1090,7 +1092,6 @@ addPrivateFunction(CHECK_UNKNOWN, NotUnknownTypeComputer.INSTANCE, true); addPrivateFunction(ANY_COLLECTION_MEMBER, CollectionMemberResultType.INSTANCE, true); addFunction(BOOLEAN_CONSTRUCTOR, ABooleanTypeComputer.INSTANCE, true); - addFunction(CARET, NumericAddSubMulDivTypeComputer.INSTANCE, true); addFunction(CIRCLE_CONSTRUCTOR, ACircleTypeComputer.INSTANCE, true); addPrivateFunction(CONCAT_NON_NULL, ConcatNonNullTypeComputer.INSTANCE, true); @@ -1143,9 +1144,9 @@ addPrivateFunction(NUMERIC_UNARY_MINUS, UnaryMinusTypeComputer.INSTANCE, true); addPrivateFunction(NUMERIC_SUBTRACT, NumericAddSubMulDivTypeComputer.INSTANCE, true); addPrivateFunction(NUMERIC_MULTIPLY, NumericAddSubMulDivTypeComputer.INSTANCE, true); - addPrivateFunction(NUMERIC_DIVIDE, NumericAddSubMulDivTypeComputer.INSTANCE, true); + addPrivateFunction(NUMERIC_DIVIDE, NumericDivideTypeComputer.INSTANCE, true); addPrivateFunction(NUMERIC_MOD, NumericAddSubMulDivTypeComputer.INSTANCE, true); - addPrivateFunction(NUMERIC_IDIV, AInt64TypeComputer.INSTANCE, true); + addPrivateFunction(NUMERIC_DIV, NumericAddSubMulDivTypeComputer.INSTANCE, true); addFunction(NUMERIC_ABS, NumericUnaryFunctionTypeComputer.INSTANCE, true); addFunction(NUMERIC_ACOS, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true); addFunction(NUMERIC_ASIN, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true); @@ -1161,6 +1162,7 @@ addFunction(NUMERIC_LN, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true); addFunction(NUMERIC_LOG, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true); addFunction(NUMERIC_PI, ADoubleTypeComputer.INSTANCE, true); + addFunction(NUMERIC_POWER, NumericAddSubMulDivTypeComputer.INSTANCE, true); addFunction(NUMERIC_SQRT, NumericDoubleOutputFunctionTypeComputer.INSTANCE, true); addFunction(NUMERIC_SIGN, NumericInt8OutputFunctionTypeComputer.INSTANCE, true); addFunction(NUMERIC_CEILING, NumericUnaryFunctionTypeComputer.INSTANCE, true); diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDivideTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDivideTypeComputer.java new file mode 100644 index 0000000..92d3bd5 --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NumericDivideTypeComputer.java @@ -0,0 +1,237 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.asterix.om.typecomputer.impl; + +import org.apache.asterix.om.exceptions.IncompatibleTypeException; +import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; +import org.apache.asterix.om.types.ATypeTag; +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; +import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression; + +/** + * Returns double if both operands are integers + */ +public class NumericDivideTypeComputer extends AbstractResultTypeComputer { + public static final NumericDivideTypeComputer INSTANCE = new NumericDivideTypeComputer(); + + private NumericDivideTypeComputer() { + } + + @Override + protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { + AbstractFunctionCallExpression functionCallExpression = (AbstractFunctionCallExpression) expr; + String funcName = functionCallExpression.getFunctionIdentifier().getName(); + IAType t1 = strippedInputTypes[0]; + IAType t2 = strippedInputTypes[1]; + ATypeTag tag1 = t1.getTypeTag(); + ATypeTag tag2 = t2.getTypeTag(); + + IAType type; + switch (tag1) { + case DOUBLE: + switch (tag2) { + case TINYINT: + case SMALLINT: + case INTEGER: + case BIGINT: + case FLOAT: + case DOUBLE: + type = BuiltinType.ADOUBLE; + break; + case ANY: + type = BuiltinType.ANY; + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + break; + case FLOAT: + switch (tag2) { + case TINYINT: + case SMALLINT: + case INTEGER: + case BIGINT: + case FLOAT: + type = BuiltinType.AFLOAT; + break; + case DOUBLE: + type = BuiltinType.ADOUBLE; + break; + case ANY: + type = BuiltinType.ANY; + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + break; + case BIGINT: + case INTEGER: + case SMALLINT: + case TINYINT: + switch (tag2) { + case TINYINT: + case SMALLINT: + case INTEGER: + case BIGINT: + case DOUBLE: + type = BuiltinType.ADOUBLE; + break; + case FLOAT: + type = BuiltinType.AFLOAT; + break; + case ANY: + type = BuiltinType.ANY; + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + break; + case ANY: + switch (tag2) { + case TINYINT: + case SMALLINT: + case INTEGER: + case BIGINT: + case FLOAT: + case ANY: + case DOUBLE: + type = BuiltinType.ANY; + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + break; + case DATE: + switch (tag2) { + case DATE: + type = BuiltinType.ADURATION; + break; + case YEARMONTHDURATION: + case DAYTIMEDURATION: + case DURATION: + type = BuiltinType.ADATE; + break; + case ANY: + type = BuiltinType.ANY; + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + break; + case TIME: + switch (tag2) { + case TIME: + type = BuiltinType.ADURATION; + break; + case YEARMONTHDURATION: + case DAYTIMEDURATION: + case DURATION: + type = BuiltinType.ATIME; + break; + case ANY: + type = BuiltinType.ANY; + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + break; + case DATETIME: + switch (tag2) { + case DATETIME: + type = BuiltinType.ADURATION; + break; + case YEARMONTHDURATION: + case DAYTIMEDURATION: + case DURATION: + type = BuiltinType.ADATETIME; + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + break; + case DURATION: + switch (tag2) { + case DATE: + type = BuiltinType.ADATE; + break; + case TIME: + type = BuiltinType.ATIME; + break; + case DATETIME: + type = BuiltinType.ADATETIME; + break; + case ANY: + type = BuiltinType.ANY; + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + break; + case YEARMONTHDURATION: + switch (tag2) { + case DATE: + type = BuiltinType.ADATE; + break; + case TIME: + type = BuiltinType.ATIME; + break; + case DATETIME: + type = BuiltinType.ADATETIME; + break; + case YEARMONTHDURATION: + type = BuiltinType.AYEARMONTHDURATION; + break; + case ANY: + type = BuiltinType.ANY; + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + break; + case DAYTIMEDURATION: + switch (tag2) { + case DATE: + type = BuiltinType.ADATE; + break; + case TIME: + type = BuiltinType.ATIME; + break; + case DATETIME: + type = BuiltinType.ADATETIME; + break; + case DAYTIMEDURATION: + type = BuiltinType.ADAYTIMEDURATION; + break; + case ANY: + type = BuiltinType.ANY; + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + break; + default: + throw new IncompatibleTypeException(funcName, tag1, tag2); + } + return type; + } +} diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java index 936415d..b06c13a 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractNumericArithmeticEval.java @@ -53,7 +53,6 @@ import org.apache.asterix.runtime.exceptions.TypeMismatchException; import org.apache.asterix.runtime.exceptions.UnderflowException; import org.apache.asterix.runtime.exceptions.UnsupportedTypeException; -import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory; import org.apache.hyracks.api.context.IHyracksTaskContext; @@ -95,8 +94,7 @@ abstract protected long evaluateTimeInstanceArithmetic(long chronon0, long chronon1) throws HyracksDataException; @Override - public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) - throws AlgebricksException { + public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) { return new IScalarEvaluatorFactory() { private static final long serialVersionUID = 1L; @@ -104,80 +102,102 @@ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws HyracksDataException { return new IScalarEvaluator() { - private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); - private DataOutput out = resultStorage.getDataOutput(); - private IPointable argPtr0 = new VoidPointable(); - private IPointable argPtr1 = new VoidPointable(); - private IScalarEvaluator evalLeft = args[0].createScalarEvaluator(ctx); - private IScalarEvaluator evalRight = args[1].createScalarEvaluator(ctx); - private double[] operandsFloating = new double[args.length]; - private long[] operandsInteger = new long[args.length]; - private int resultType; - static protected final int typeInt8 = 1; - static protected final int typeInt16 = 2; - static protected final int typeInt32 = 3; - static protected final int typeInt64 = 4; - static protected final int typeFloat = 5; - static protected final int typeDouble = 6; + private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); + private final DataOutput out = resultStorage.getDataOutput(); + private final IPointable argPtr0 = new VoidPointable(); + private final IPointable argPtr1 = new VoidPointable(); + private final IScalarEvaluator evalLeft = args[0].createScalarEvaluator(ctx); + private final IScalarEvaluator evalRight = args[1].createScalarEvaluator(ctx); + private final double[] operandsFloating = new double[args.length]; + private final long[] operandsInteger = new long[args.length]; - protected AMutableFloat aFloat = new AMutableFloat(0); - protected AMutableDouble aDouble = new AMutableDouble(0); - protected AMutableInt64 aInt64 = new AMutableInt64(0); - protected AMutableInt32 aInt32 = new AMutableInt32(0); - protected AMutableInt16 aInt16 = new AMutableInt16((short) 0); - protected AMutableInt8 aInt8 = new AMutableInt8((byte) 0); + private final AMutableFloat aFloat = new AMutableFloat(0); + private final AMutableDouble aDouble = new AMutableDouble(0); + private final AMutableInt64 aInt64 = new AMutableInt64(0); + private final AMutableInt32 aInt32 = new AMutableInt32(0); + private final AMutableInt16 aInt16 = new AMutableInt16((short) 0); + private final AMutableInt8 aInt8 = new AMutableInt8((byte) 0); - protected AMutableDuration aDuration = new AMutableDuration(0, 0); - protected AMutableDate aDate = new AMutableDate(0); - protected AMutableTime aTime = new AMutableTime(0); - protected AMutableDateTime aDatetime = new AMutableDateTime(0); + private final AMutableDuration aDuration = new AMutableDuration(0, 0); + private final AMutableDate aDate = new AMutableDate(0); + private final AMutableTime aTime = new AMutableTime(0); + private final AMutableDateTime aDatetime = new AMutableDateTime(0); - private ATypeTag typeTag; @SuppressWarnings("rawtypes") - private ISerializerDeserializer serde; + private final ISerializerDeserializer int8Serde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT8); + @SuppressWarnings("rawtypes") + private final ISerializerDeserializer int16Serde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT16); + @SuppressWarnings("rawtypes") + private final ISerializerDeserializer int32Serde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT32); + @SuppressWarnings("rawtypes") + private final ISerializerDeserializer int64Serde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64); + @SuppressWarnings("rawtypes") + private final ISerializerDeserializer floatSerde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AFLOAT); + @SuppressWarnings("rawtypes") + private final ISerializerDeserializer doubleSerde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADOUBLE); + @SuppressWarnings("rawtypes") + private final ISerializerDeserializer dateSerde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADATE); + @SuppressWarnings("rawtypes") + private final ISerializerDeserializer timeSerde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ATIME); + @SuppressWarnings("rawtypes") + private final ISerializerDeserializer dateTimeSerde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADATETIME); + @SuppressWarnings("rawtypes") + private final ISerializerDeserializer durationSerde = + SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ADURATION); - @SuppressWarnings("unchecked") @Override + @SuppressWarnings("unchecked") public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException { - resultStorage.reset(); - resultType = 0; - int currentType; evalLeft.evaluate(tuple, argPtr0); evalRight.evaluate(tuple, argPtr1); - for (int i = 0; i < args.length; i++) { + resultStorage.reset(); + + ATypeTag argTypeMax = null; + + for (int i = 0; i < 2; i++) { IPointable argPtr = i == 0 ? argPtr0 : argPtr1; byte[] bytes = argPtr.getByteArray(); int offset = argPtr.getStartOffset(); - typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes[offset]); + ATypeTag currentType; + ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes[offset]); switch (typeTag) { case TINYINT: - currentType = typeInt8; + currentType = ATypeTag.TINYINT; operandsInteger[i] = AInt8SerializerDeserializer.getByte(bytes, offset + 1); operandsFloating[i] = operandsInteger[i]; break; case SMALLINT: - currentType = typeInt16; + currentType = ATypeTag.SMALLINT; operandsInteger[i] = AInt16SerializerDeserializer.getShort(bytes, offset + 1); operandsFloating[i] = operandsInteger[i]; break; case INTEGER: - currentType = typeInt32; + currentType = ATypeTag.INTEGER; operandsInteger[i] = AInt32SerializerDeserializer.getInt(bytes, offset + 1); operandsFloating[i] = operandsInteger[i]; break; case BIGINT: - currentType = typeInt64; + currentType = ATypeTag.BIGINT; operandsInteger[i] = AInt64SerializerDeserializer.getLong(bytes, offset + 1); operandsFloating[i] = operandsInteger[i]; break; case FLOAT: - currentType = typeFloat; + currentType = ATypeTag.FLOAT; operandsFloating[i] = AFloatSerializerDeserializer.getFloat(bytes, offset + 1); break; case DOUBLE: - currentType = typeDouble; + currentType = ATypeTag.DOUBLE; operandsFloating[i] = ADoubleSerializerDeserializer.getDouble(bytes, offset + 1); break; case DATE: @@ -186,7 +206,7 @@ case DURATION: case YEARMONTHDURATION: case DAYTIMEDURATION: - evaluateTemporalArthmeticOperation(typeTag); + evaluateTemporalArithmeticOperation(typeTag); result.set(resultStorage); return; default: @@ -201,17 +221,17 @@ ATypeTag.SERIALIZED_DAY_TIME_DURATION_TYPE_TAG); } - if (resultType < currentType) { - resultType = currentType; + if (i == 0 || currentType.ordinal() > argTypeMax.ordinal()) { + argTypeMax = currentType; } } + + ATypeTag resultType = getNumericResultType(argTypeMax); long lres; double dres; switch (resultType) { - case typeInt8: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.AINT8); + case TINYINT: lres = evaluateInteger(operandsInteger[0], operandsInteger[1]); if (lres > Byte.MAX_VALUE) { throw new OverflowException(getIdentifier()); @@ -220,11 +240,9 @@ throw new UnderflowException(getIdentifier()); } aInt8.setValue((byte) lres); - serde.serialize(aInt8, out); + int8Serde.serialize(aInt8, out); break; - case typeInt16: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.AINT16); + case SMALLINT: lres = evaluateInteger(operandsInteger[0], operandsInteger[1]); if (lres > Short.MAX_VALUE) { throw new OverflowException(getIdentifier()); @@ -233,11 +251,9 @@ throw new UnderflowException(getIdentifier()); } aInt16.setValue((short) lres); - serde.serialize(aInt16, out); + int16Serde.serialize(aInt16, out); break; - case typeInt32: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.AINT32); + case INTEGER: lres = evaluateInteger(operandsInteger[0], operandsInteger[1]); if (lres > Integer.MAX_VALUE) { throw new OverflowException(getIdentifier()); @@ -246,18 +262,14 @@ throw new UnderflowException(getIdentifier()); } aInt32.setValue((int) lres); - serde.serialize(aInt32, out); + int32Serde.serialize(aInt32, out); break; - case typeInt64: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.AINT64); + case BIGINT: lres = evaluateInteger(operandsInteger[0], operandsInteger[1]); aInt64.setValue(lres); - serde.serialize(aInt64, out); + int64Serde.serialize(aInt64, out); break; - case typeFloat: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.AFLOAT); + case FLOAT: dres = evaluateDouble(operandsFloating[0], operandsFloating[1]); if (dres > Float.MAX_VALUE) { throw new OverflowException(getIdentifier()); @@ -266,20 +278,19 @@ throw new UnderflowException(getIdentifier()); } aFloat.setValue((float) dres); - serde.serialize(aFloat, out); + floatSerde.serialize(aFloat, out); break; - case typeDouble: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ADOUBLE); - aDouble.setValue(evaluateDouble(operandsFloating[0], operandsFloating[1])); - serde.serialize(aDouble, out); + case DOUBLE: + dres = evaluateDouble(operandsFloating[0], operandsFloating[1]); + aDouble.setValue(dres); + doubleSerde.serialize(aDouble, out); break; } result.set(resultStorage); } @SuppressWarnings("unchecked") - private void evaluateTemporalArthmeticOperation(ATypeTag leftType) throws HyracksDataException { + private void evaluateTemporalArithmeticOperation(ATypeTag leftType) throws HyracksDataException { byte[] bytes1 = argPtr1.getByteArray(); int offset1 = argPtr1.getStartOffset(); ATypeTag rightType = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes1[offset1]); @@ -288,10 +299,7 @@ if (rightType == leftType) { - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ADURATION); - - long leftChronon = 0, rightChronon = 0, dayTime = 0; + long leftChronon = 0, rightChronon = 0, dayTime; int yearMonth = 0; @@ -301,7 +309,6 @@ * GregorianCalendarSystem.CHRONON_OF_DAY; rightChronon = ADateSerializerDeserializer.getChronon(bytes1, offset1 + 1) * GregorianCalendarSystem.CHRONON_OF_DAY; - break; case TIME: leftChronon = ATimeSerializerDeserializer.getChronon(bytes0, offset0 + 1); @@ -329,20 +336,19 @@ dayTime = evaluateTimeInstanceArithmetic(leftChronon, rightChronon); aDuration.setValue(yearMonth, dayTime); - - serde.serialize(aDuration, out); + durationSerde.serialize(aDuration, out); } else { long chronon = 0, dayTime = 0; int yearMonth = 0; ATypeTag resultType = null; + ISerializerDeserializer serde = null; boolean isTimeOnly = false; switch (leftType) { case TIME: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ATIME); + serde = timeSerde; chronon = ATimeSerializerDeserializer.getChronon(bytes0, offset0 + 1); isTimeOnly = true; resultType = ATypeTag.TIME; @@ -362,15 +368,13 @@ } break; case DATE: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ADATE); + serde = dateSerde; resultType = ATypeTag.DATE; chronon = ADateSerializerDeserializer.getChronon(bytes0, offset0 + 1) * GregorianCalendarSystem.CHRONON_OF_DAY; case DATETIME: if (leftType == ATypeTag.DATETIME) { - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ADATETIME); + serde = dateTimeSerde; resultType = ATypeTag.DATETIME; chronon = ADateTimeSerializerDeserializer.getChronon(bytes0, offset0 + 1); } @@ -398,14 +402,12 @@ AYearMonthDurationSerializerDeserializer.getYearMonth(bytes0, offset0 + 1); switch (rightType) { case DATETIME: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ADATETIME); + serde = dateTimeSerde; resultType = ATypeTag.DATETIME; chronon = ADateTimeSerializerDeserializer.getChronon(bytes1, offset1 + 1); break; case DATE: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ADATE); + serde = dateSerde; resultType = ATypeTag.DATE; chronon = ADateSerializerDeserializer.getChronon(bytes1, offset1 + 1) * GregorianCalendarSystem.CHRONON_OF_DAY; @@ -425,22 +427,19 @@ } switch (rightType) { case DATETIME: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ADATETIME); + serde = dateTimeSerde; resultType = ATypeTag.DATETIME; chronon = ADateTimeSerializerDeserializer.getChronon(bytes1, offset1 + 1); break; case DATE: - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ADATE); + serde = dateSerde; resultType = ATypeTag.DATE; chronon = ADateSerializerDeserializer.getChronon(bytes1, offset1 + 1) * GregorianCalendarSystem.CHRONON_OF_DAY; break; case TIME: if (yearMonth == 0) { - serde = SerializerDeserializerProvider.INSTANCE - .getSerializerDeserializer(BuiltinType.ATIME); + serde = timeSerde; resultType = ATypeTag.TIME; chronon = ATimeSerializerDeserializer.getChronon(bytes1, offset1 + 1); isTimeOnly = true; @@ -486,4 +485,8 @@ } }; } + + protected ATypeTag getNumericResultType(ATypeTag argTypeMax) { + return argTypeMax; + } } diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivDescriptor.java similarity index 64% copy from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java copy to asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivDescriptor.java index 0079a8a..33edc7b 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivDescriptor.java @@ -16,65 +16,58 @@ * specific language governing permissions and limitations * under the License. */ + package org.apache.asterix.runtime.evaluators.functions; +import org.apache.asterix.common.exceptions.ErrorCode; +import org.apache.asterix.common.exceptions.RuntimeDataException; 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.exceptions.OverflowException; import org.apache.asterix.runtime.exceptions.UnsupportedTypeException; +import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException; import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; import org.apache.hyracks.api.exceptions.HyracksDataException; -import com.google.common.math.LongMath; - -public class NumericCaretDescriptor extends AbstractNumericArithmeticEval { - +public class NumericDivDescriptor extends AbstractNumericArithmeticEval { private static final long serialVersionUID = 1L; public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { public IFunctionDescriptor createFunctionDescriptor() { - return new NumericCaretDescriptor(); + return new NumericDivDescriptor(); } }; - /* (non-Javadoc) - * @see org.apache.asterix.runtime.evaluators.functions.AbstractNumericArithmeticEval#evaluateInteger(long, long) - */ - @Override - protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException { - if (rhs > Integer.MAX_VALUE) { - throw new OverflowException(getIdentifier()); - } - return LongMath.checkedPow(lhs, (int) rhs); - } - - /* (non-Javadoc) - * @see org.apache.asterix.runtime.evaluators.functions.AbstractNumericArithmeticEval#evaluateDouble(double, double) - */ - @Override - protected double evaluateDouble(double lhs, double rhs) throws HyracksDataException { - return Math.pow(lhs, rhs); - } - - /* (non-Javadoc) - * @see org.apache.asterix.om.functions.AbstractFunctionDescriptor#getIdentifier() - */ @Override public FunctionIdentifier getIdentifier() { - return BuiltinFunctions.CARET; + return BuiltinFunctions.NUMERIC_DIV; } @Override - protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly) - throws HyracksDataException { - throw new UnsupportedTypeException(getIdentifier().getName(), ATypeTag.SERIALIZED_DURATION_TYPE_TAG); + protected double evaluateDouble(double lhs, double rhs) { + return lhs / rhs; + } + + @Override + protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException { + if (rhs == 0) { + throw new RuntimeDataException(ErrorCode.DIVISION_BY_ZERO); + } + if ((lhs == Long.MIN_VALUE) && (rhs == -1L)) { + throw new OverflowException(getIdentifier()); + } + return lhs / rhs; + } + + @Override + protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly) { + throw new NotImplementedException("Divide operation is not defined for temporal types"); } @Override protected long evaluateTimeInstanceArithmetic(long chronon0, long chronon1) throws HyracksDataException { - throw new UnsupportedTypeException(getIdentifier().getName(), ATypeTag.SERIALIZED_TIME_TYPE_TAG); + throw new UnsupportedTypeException(getIdentifier(), ATypeTag.SERIALIZED_TIME_TYPE_TAG); } - } diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java index 77c94bf..868f3b5 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericDivideDescriptor.java @@ -18,21 +18,18 @@ */ package org.apache.asterix.runtime.evaluators.functions; -import org.apache.asterix.common.exceptions.ErrorCode; -import org.apache.asterix.common.exceptions.RuntimeDataException; 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.exceptions.OverflowException; import org.apache.asterix.runtime.exceptions.UnsupportedTypeException; import org.apache.hyracks.algebricks.common.exceptions.NotImplementedException; import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier; import org.apache.hyracks.api.exceptions.HyracksDataException; public class NumericDivideDescriptor extends AbstractNumericArithmeticEval { - private static final long serialVersionUID = 1L; + public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { public IFunctionDescriptor createFunctionDescriptor() { return new NumericDivideDescriptor(); @@ -45,14 +42,8 @@ } @Override - protected long evaluateInteger(long lhs, long rhs) throws HyracksDataException { - if (rhs == 0) { - throw new RuntimeDataException(ErrorCode.DIVISION_BY_ZERO); - } - if ((lhs == Long.MIN_VALUE) && (rhs == -1L)) { - throw new OverflowException(getIdentifier()); - } - return lhs / rhs; + protected ATypeTag getNumericResultType(ATypeTag argTypeMax) { + return argTypeMax.ordinal() < ATypeTag.FLOAT.ordinal() ? ATypeTag.DOUBLE : argTypeMax; } @Override @@ -61,8 +52,12 @@ } @Override - protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly) - throws HyracksDataException { + protected long evaluateInteger(long lhs, long rhs) { + throw new IllegalStateException(); + } + + @Override + protected long evaluateTimeDurationArithmetic(long chronon, int yearMonth, long dayTime, boolean isTimeOnly) { throw new NotImplementedException("Divide operation is not defined for temporal types"); } diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericPowerDescriptor.java similarity index 94% rename from asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java rename to asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericPowerDescriptor.java index 0079a8a..ae7f019 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericCaretDescriptor.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/NumericPowerDescriptor.java @@ -29,13 +29,13 @@ import com.google.common.math.LongMath; -public class NumericCaretDescriptor extends AbstractNumericArithmeticEval { +public class NumericPowerDescriptor extends AbstractNumericArithmeticEval { private static final long serialVersionUID = 1L; public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { public IFunctionDescriptor createFunctionDescriptor() { - return new NumericCaretDescriptor(); + return new NumericPowerDescriptor(); } }; @@ -63,7 +63,7 @@ */ @Override public FunctionIdentifier getIdentifier() { - return BuiltinFunctions.CARET; + return BuiltinFunctions.NUMERIC_POWER; } @Override 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 9a09184..9fecf34 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 @@ -185,7 +185,8 @@ import org.apache.asterix.runtime.evaluators.functions.NumericATanDescriptor; import org.apache.asterix.runtime.evaluators.functions.NumericAbsDescriptor; import org.apache.asterix.runtime.evaluators.functions.NumericAddDescriptor; -import org.apache.asterix.runtime.evaluators.functions.NumericCaretDescriptor; +import org.apache.asterix.runtime.evaluators.functions.NumericDivDescriptor; +import org.apache.asterix.runtime.evaluators.functions.NumericPowerDescriptor; import org.apache.asterix.runtime.evaluators.functions.NumericCeilingDescriptor; import org.apache.asterix.runtime.evaluators.functions.NumericCosDescriptor; import org.apache.asterix.runtime.evaluators.functions.NumericDegreesDescriptor; @@ -492,10 +493,11 @@ fc.addGenerated(NumericUnaryMinusDescriptor.FACTORY); fc.addGenerated(NumericAddDescriptor.FACTORY); fc.addGenerated(NumericDivideDescriptor.FACTORY); + fc.addGenerated(NumericDivDescriptor.FACTORY); fc.addGenerated(NumericMultiplyDescriptor.FACTORY); fc.addGenerated(NumericSubDescriptor.FACTORY); fc.addGenerated(NumericModuloDescriptor.FACTORY); - fc.addGenerated(NumericCaretDescriptor.FACTORY); + fc.addGenerated(NumericPowerDescriptor.FACTORY); fc.addGenerated(NotDescriptor.FACTORY); fc.addGenerated(LenDescriptor.FACTORY); fc.addGenerated(NumericAbsDescriptor.FACTORY); -- To view, visit https://asterix-gerrit.ics.uci.edu/2630 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7c6b0704ce60a03dd3c10e1c75cb9761acc56536 Gerrit-PatchSet: 3 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Dmitry Lychagin <[email protected]> Gerrit-Reviewer: Anon. E. Moose #1000171 Gerrit-Reviewer: Dmitry Lychagin <[email protected]> Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Till Westmann <[email protected]>
