ソースを参照

HPCC-8352 Update comments to clarify the code

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 12 年 前
コミット
fb879a5c01

+ 22 - 4
common/deftype/defvalue.cpp

@@ -2528,11 +2528,13 @@ IValue * divideValues(IValue * left, IValue * right, DBZaction onZero)
 {
     Owned<ITypeInfo> pnt = getPromotedMulDivType(left->queryType(), right->queryType());
 
-    //All non zero values should return false when cast to boolean
+    //Use a cast to a boolean as a shortcut for testing against zero
     if (!right->getBoolValue())
     {
+        //If no action is selected, return NULL so the expression doesn't get constant folded.
         if (onZero == DBZnone)
             return NULL;
+
         if (onZero == DBZfail)
             rtlFailDivideByZero();
     }
@@ -2559,7 +2561,14 @@ IValue * divideValues(IValue * left, IValue * right, DBZaction onZero)
     {
         double lv = left->getRealValue();
         double rv = right->getRealValue();
-        double res = rv ? lv / rv : 0.0;
+        double res;
+        if (rv)
+            res = lv / rv;
+        else if (onZero == DBZnan)
+            res =  rtlCreateRealNull();
+        else
+            res = 0.0;
+
         return createRealValue(res, pnt.getClear());
     }
     case type_decimal:
@@ -2580,11 +2589,13 @@ IValue * modulusValues(IValue * left, IValue * right, DBZaction onZero)
 {
     Owned<ITypeInfo> pnt = getPromotedMulDivType(left->queryType(), right->queryType());
     
-    //All non zero values should return false when cast to boolean
+    //Use a cast to a boolean as a shortcut for testing against zero
     if (!right->getBoolValue())
     {
+        //If no action is selected, return NULL so the expression doesn't get constant folded.
         if (onZero == DBZnone)
             return NULL;
+
         if (onZero == DBZfail)
             rtlFailDivideByZero();
     }
@@ -2610,7 +2621,14 @@ IValue * modulusValues(IValue * left, IValue * right, DBZaction onZero)
     case type_real:
     {
         double rv = right->getRealValue();
-        double res = rv ? fmod(left->getRealValue(), rv) : 0;
+        double res;
+        if (rv)
+            res = fmod(left->getRealValue(), rv);
+        else if (onZero == DBZnan)
+            res =  rtlCreateRealNull();
+        else
+            res = 0.0;
+
         return createRealValue(res, pnt.getClear());
     }
     case type_decimal:

+ 2 - 0
ecl/hqlcpp/hqlcerrors.hpp

@@ -208,6 +208,7 @@
 #define HQLERR_ScalarOutputWithinApply          4186
 #define HQLERR_EmbeddedTypeNotSupported_X       4187
 #define HQLERR_MaximumSizeLessThanMinimum_XY    4188
+#define HQLERR_UnexpectedOptionValue_XY         4189
 
 //Warnings....
 #define HQLWRN_PersistDataNotLikely             4500
@@ -488,6 +489,7 @@
 #define HQLERR_KeyedJoinNoRightIndex_X_Text     "Right dataset (%s) for a keyed join isn't a key"
 #define HQLERR_EmbeddedTypeNotSupported_X_Text  "Type %s not supported for embedded/external scripts"
 #define HQLERR_MaximumSizeLessThanMinimum_XY_Text "Maximum size (%u) for this record is lower than the minimum (%u)"
+#define HQLERR_UnexpectedOptionValue_XY_Text    "Unexpected value for option %s: %s"
 
 //Warnings.
 #define HQLWRN_CannotRecreateDistribution_Text  "Cannot recreate the distribution for a persistent dataset"

+ 2 - 1
ecl/hqlcpp/hqlcpp.cpp

@@ -1729,6 +1729,8 @@ void HqlCppTranslator::cacheOptions()
         options.divideByZeroAction = DBZnan;
     else if (strieq(val.str(), "fail") || strieq(val.str(), "throw"))
         options.divideByZeroAction = DBZfail;
+    else if (val.length())
+        throwError2(HQLERR_UnexpectedOptionValue_XY, "divideByZero", val.str());
 
     //The following cases handle options whose default values are dependent on other options.  
     //Or where one debug options sets more than one option
@@ -7044,7 +7046,6 @@ void HqlCppTranslator::doBuildDivideByZero(BuildCtx & ctx, const CHqlBoundTarget
                 nan.setown(bindFunctionCall(createRealNullAtom, noArgs));
             }
 
-            //MORE:
             if (target)
                 assignBound(ctx, *target, nan);
             else

+ 0 - 2
ecl/regress/indexread32.ecl

@@ -16,8 +16,6 @@
 ############################################################################## */
 
 #option ('globalFold', false);
-#option ('checkThorRestrictions', false);
-
 d := dataset('~local::rkc::person', { string15 name, unsigned8 filepos{virtual(fileposition)} }, flat);
 
 i := stepped(index(d, { name, filepos }, {},'\\home\\person.name_first.key', hint(thisIsAHint(5))), filepos,hint(anotherHint));

+ 2 - 1
rtl/nbcd/nbcd.cpp

@@ -342,7 +342,8 @@ Decimal & Decimal::power(int value)
     //This probably gives slightly more expected results, but both suffer from rounding errors.
     Decimal reciprocal;
     reciprocal.setInt(1);
-    reciprocal.divide(*this, DBZzero);  // MORE: This should probably be passed in
+    // DBZzero means 0D^-3 will return 0 instead of throwing an error if divide by zero is set to DBZfail.
+    reciprocal.divide(*this, DBZzero);
     set(reciprocal);
     doPower((unsigned)-value);
     return *this;

+ 2 - 1
rtl/nbcd/nbcd.hpp

@@ -84,7 +84,8 @@ public:
     void getClipPrecision(unsigned & digits, unsigned & precision);
     void getPrecision(unsigned & digits, unsigned & precison);
 
-    bool isValid() const { return true; } // MORE: Should extend to support Nans
+    // MORE: We could support NaNs for decimals at a later date by adding a member to this class.
+    bool isValid() const { return true; }
 
     void set(const Decimal & value);
     void setCString(const char * buffer);

+ 47 - 0
testing/ecl/dbz1.ecl

@@ -0,0 +1,47 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2013 HPCC Systems.
+
+    Licensed 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.
+############################################################################## */
+
+//nothor
+//nothorlcr
+//noroxie
+
+//Test division by zero - default action to return 0
+#option ('divideByZero', '0'); 
+
+unsigned cintZero := 0;
+real crealZero := 0.0;
+decimal10_2 cdecZero := 0.0D;
+
+unsigned intZero := 0 : stored('intZero');
+real realZero := 0.0 : stored('realZero');
+decimal10_2 decZero := 0.0D : stored('decZero');
+
+output(100 DIV 1);
+output(100.0 / 1.0);
+output(100.1D / 1.0D);
+
+output(100 DIV cintZero);
+output(100.0 / crealZero);
+output(100.1D / cdecZero);
+            
+output(5 * (101 DIV cintZero));
+output(5 * (101.0 / crealZero));
+output(5D * (101.1D / cdecZero));
+            
+output(100 DIV intZero);
+output(100.0 / realZero);
+output(100.1D / decZero);

+ 33 - 0
testing/ecl/dbz2a.ecl

@@ -0,0 +1,33 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2013 HPCC Systems.
+
+    Licensed 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.
+############################################################################## */
+
+//nothor
+//nothorlcr
+//noroxie
+
+//Test division by zero - default action to return 0
+#option ('divideByZero', 'fail'); 
+
+unsigned cintZero := 0;
+real crealZero := 0.0;
+decimal10_2 cdecZero := 0.0D;
+
+unsigned intZero := 0 : stored('intZero');
+real realZero := 0.0 : stored('realZero');
+decimal10_2 decZero := 0.0D : stored('decZero');
+
+output(100 DIV intZero);

+ 33 - 0
testing/ecl/dbz2b.ecl

@@ -0,0 +1,33 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2013 HPCC Systems.
+
+    Licensed 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.
+############################################################################## */
+
+//nothor
+//nothorlcr
+//noroxie
+
+//Test division by zero - default action to return 0
+#option ('divideByZero', 'fail'); 
+
+unsigned cintZero := 0;
+real crealZero := 0.0;
+decimal10_2 cdecZero := 0.0D;
+
+unsigned intZero := 0 : stored('intZero');
+real realZero := 0.0 : stored('realZero');
+decimal10_2 decZero := 0.0D : stored('decZero');
+
+output(100.0 / realZero);

+ 33 - 0
testing/ecl/dbz2c.ecl

@@ -0,0 +1,33 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2013 HPCC Systems.
+
+    Licensed 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.
+############################################################################## */
+
+//nothor
+//nothorlcr
+//noroxie
+
+//Test division by zero - default action to return 0
+#option ('divideByZero', 'fail'); 
+
+unsigned cintZero := 0;
+real crealZero := 0.0;
+decimal10_2 cdecZero := 0.0D;
+
+unsigned intZero := 0 : stored('intZero');
+real realZero := 0.0 : stored('realZero');
+decimal10_2 decZero := 0.0D : stored('decZero');
+
+output(100.1D / decZero);

+ 79 - 0
testing/ecl/dbz3.ecl

@@ -0,0 +1,79 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2013 HPCC Systems.
+
+    Licensed 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.
+############################################################################## */
+
+//nothor
+//nothorlcr
+//noroxie
+
+//Test division by zero - fail instead of returning 0
+#option ('divideByZero', 'nan'); 
+
+unsigned cintZero := 0;
+real crealZero := 0.0;
+decimal10_2 cdecZero := 0.0D;
+
+unsigned intZero := 0 : stored('intZero');
+real realZero := 0.0 : stored('realZero');
+decimal10_2 decZero := 0.0D : stored('decZero');
+
+output(NOT ISNULL(100 DIV 1));
+output(NOT ISNULL(100.0 / 1.0));
+output(NOT ISNULL(100.1D / 1.0D));
+
+output('Constant Divide:');
+output(ISNULL(100 DIV cintZero));
+output(ISNULL(100.0 / crealZero));
+output(ISNULL(100.1D / cdecZero));
+            
+output('Constant Divide Multiply:');
+output(ISNULL(5 * (101 DIV cintZero)));
+output(ISNULL(5 * (101.0 / crealZero)));
+output(ISNULL(5D * (101.1D / cdecZero)));
+            
+output('Runtime Divide:');
+output(ISNULL(100 DIV intZero));
+output(ISNULL(100.0 / realZero));
+output(ISNULL(100.1D / decZero));
+
+//--- check modulus
+output('Modulus:');
+
+output(NOT ISNULL(100 % 1));
+output(NOT ISNULL(100.0 % 1.0));
+output(NOT ISNULL(100.1D % 1.0D));
+
+output('Constant Modulus:');
+output(ISNULL(100 % cintZero));
+output(ISNULL(100.0 % crealZero));
+output(ISNULL(100.1D % cdecZero));
+            
+output('Constant Modulus Multiply:');
+output(ISNULL(5 * (101 % cintZero)));
+output(ISNULL(5 * (101.0 % crealZero)));
+output(ISNULL(5D * (101.1D % cdecZero)));
+            
+output('Runtime Modulus:');
+output(ISNULL(100 % intZero));
+output(ISNULL(100.0 % realZero));
+output(ISNULL(100.1D % decZero));
+
+output('Miscellaneous');
+output(100.0 / crealZero);
+output(100.0 / realZero);
+output(1.0e300 * nofold(1.0e300));
+output(-1.0e300 * nofold(1.0e300));
+

+ 36 - 0
testing/ecl/key/dbz1.xml

@@ -0,0 +1,36 @@
+<Dataset name='Result 1'>
+ <Row><Result_1>100</Result_1></Row>
+</Dataset>
+<Dataset name='Result 2'>
+ <Row><Result_2>100.0</Result_2></Row>
+</Dataset>
+<Dataset name='Result 3'>
+ <Row><Result_3>100.1</Result_3></Row>
+</Dataset>
+<Dataset name='Result 4'>
+ <Row><Result_4>0</Result_4></Row>
+</Dataset>
+<Dataset name='Result 5'>
+ <Row><Result_5>0.0</Result_5></Row>
+</Dataset>
+<Dataset name='Result 6'>
+ <Row><Result_6>0</Result_6></Row>
+</Dataset>
+<Dataset name='Result 7'>
+ <Row><Result_7>0</Result_7></Row>
+</Dataset>
+<Dataset name='Result 8'>
+ <Row><Result_8>0.0</Result_8></Row>
+</Dataset>
+<Dataset name='Result 9'>
+ <Row><Result_9>0</Result_9></Row>
+</Dataset>
+<Dataset name='Result 10'>
+ <Row><Result_10>0</Result_10></Row>
+</Dataset>
+<Dataset name='Result 11'>
+ <Row><Result_11>0.0</Result_11></Row>
+</Dataset>
+<Dataset name='Result 12'>
+ <Row><Result_12>0</Result_12></Row>
+</Dataset>

+ 1 - 0
testing/ecl/key/dbz2a.xml

@@ -0,0 +1 @@
+<Error><source>eclagent</source><code>-1</code><message>System error: -1: Division by zero</message></Error>

+ 1 - 0
testing/ecl/key/dbz2b.xml

@@ -0,0 +1 @@
+<Error><source>eclagent</source><code>-1</code><message>System error: -1: Division by zero</message></Error>

+ 1 - 0
testing/ecl/key/dbz2c.xml

@@ -0,0 +1 @@
+<Error><source>eclagent</source><code>-1</code><message>System error: -1: Division by zero</message></Error>

+ 108 - 0
testing/ecl/key/dbz3.xml

@@ -0,0 +1,108 @@
+<Dataset name='Result 1'>
+ <Row><Result_1>true</Result_1></Row>
+</Dataset>
+<Dataset name='Result 2'>
+ <Row><Result_2>true</Result_2></Row>
+</Dataset>
+<Dataset name='Result 3'>
+ <Row><Result_3>true</Result_3></Row>
+</Dataset>
+<Dataset name='Result 4'>
+ <Row><Result_4>Constant Divide:</Result_4></Row>
+</Dataset>
+<Dataset name='Result 5'>
+ <Row><Result_5>false</Result_5></Row>
+</Dataset>
+<Dataset name='Result 6'>
+ <Row><Result_6>true</Result_6></Row>
+</Dataset>
+<Dataset name='Result 7'>
+ <Row><Result_7>false</Result_7></Row>
+</Dataset>
+<Dataset name='Result 8'>
+ <Row><Result_8>Constant Divide Multiply:</Result_8></Row>
+</Dataset>
+<Dataset name='Result 9'>
+ <Row><Result_9>false</Result_9></Row>
+</Dataset>
+<Dataset name='Result 10'>
+ <Row><Result_10>true</Result_10></Row>
+</Dataset>
+<Dataset name='Result 11'>
+ <Row><Result_11>false</Result_11></Row>
+</Dataset>
+<Dataset name='Result 12'>
+ <Row><Result_12>Runtime Divide:</Result_12></Row>
+</Dataset>
+<Dataset name='Result 13'>
+ <Row><Result_13>false</Result_13></Row>
+</Dataset>
+<Dataset name='Result 14'>
+ <Row><Result_14>true</Result_14></Row>
+</Dataset>
+<Dataset name='Result 15'>
+ <Row><Result_15>false</Result_15></Row>
+</Dataset>
+<Dataset name='Result 16'>
+ <Row><Result_16>Modulus:</Result_16></Row>
+</Dataset>
+<Dataset name='Result 17'>
+ <Row><Result_17>true</Result_17></Row>
+</Dataset>
+<Dataset name='Result 18'>
+ <Row><Result_18>true</Result_18></Row>
+</Dataset>
+<Dataset name='Result 19'>
+ <Row><Result_19>true</Result_19></Row>
+</Dataset>
+<Dataset name='Result 20'>
+ <Row><Result_20>Constant Modulus:</Result_20></Row>
+</Dataset>
+<Dataset name='Result 21'>
+ <Row><Result_21>false</Result_21></Row>
+</Dataset>
+<Dataset name='Result 22'>
+ <Row><Result_22>false</Result_22></Row>
+</Dataset>
+<Dataset name='Result 23'>
+ <Row><Result_23>false</Result_23></Row>
+</Dataset>
+<Dataset name='Result 24'>
+ <Row><Result_24>Constant Modulus Multiply:</Result_24></Row>
+</Dataset>
+<Dataset name='Result 25'>
+ <Row><Result_25>false</Result_25></Row>
+</Dataset>
+<Dataset name='Result 26'>
+ <Row><Result_26>false</Result_26></Row>
+</Dataset>
+<Dataset name='Result 27'>
+ <Row><Result_27>false</Result_27></Row>
+</Dataset>
+<Dataset name='Result 28'>
+ <Row><Result_28>Runtime Modulus:</Result_28></Row>
+</Dataset>
+<Dataset name='Result 29'>
+ <Row><Result_29>false</Result_29></Row>
+</Dataset>
+<Dataset name='Result 30'>
+ <Row><Result_30>false</Result_30></Row>
+</Dataset>
+<Dataset name='Result 31'>
+ <Row><Result_31>false</Result_31></Row>
+</Dataset>
+<Dataset name='Result 32'>
+ <Row><Result_32>Miscellaneous</Result_32></Row>
+</Dataset>
+<Dataset name='Result 33'>
+ <Row><Result_33>nan</Result_33></Row>
+</Dataset>
+<Dataset name='Result 34'>
+ <Row><Result_34>nan</Result_34></Row>
+</Dataset>
+<Dataset name='Result 35'>
+ <Row><Result_35>inf</Result_35></Row>
+</Dataset>
+<Dataset name='Result 36'>
+ <Row><Result_36>-inf</Result_36></Row>
+</Dataset>