]> source.dussan.org Git - poi.git/commitdiff
Fix for bug 46647 - COUNTIF NE operator and other special cases involving type conversion
authorJosh Micich <josh@apache.org>
Mon, 2 Feb 2009 19:42:57 +0000 (19:42 +0000)
committerJosh Micich <josh@apache.org>
Mon, 2 Feb 2009 19:42:57 +0000 (19:42 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@740088 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/record/formula/functions/Countif.java
src/testcases/org/apache/poi/hssf/record/formula/functions/TestCountFuncs.java

index 17a02ee598a05bb162bbc4c02af1946f210d2e46..e8b0f419c44d174460ff13851f43e4d1b9f49c22 100644 (file)
@@ -37,6 +37,7 @@
 
                <!-- Don't forget to update status.xml too! -->
         <release version="3.5-beta5" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">46647 - Fixed COUNTIF NE operator and other special cases involving type conversion</action>
            <action dev="POI-DEVELOPERS" type="add">46635 - Added a method to remove slides</action>
            <action dev="POI-DEVELOPERS" type="fix">46520 - Fixed HSSFFont.applyFont() to properly apply font to overlapping regions</action>
            <action dev="POI-DEVELOPERS" type="fix">46545 - Fixed ObjRecord to ignore excessive padding written by previous POI versions</action>
index c4c22452d3c75fbc129de275191bfe2008df5125..c96bd23f6ad68989c5865fa6e68d8cf54c4e8398 100644 (file)
@@ -34,6 +34,7 @@
        <!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.5-beta5" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">46647 - Fixed COUNTIF NE operator and other special cases involving type conversion</action>
            <action dev="POI-DEVELOPERS" type="add">46635 - Added a method to remove slides</action>
            <action dev="POI-DEVELOPERS" type="fix">46520 - Fixed HSSFFont.applyFont() to properly apply font to overlapping regions</action>
            <action dev="POI-DEVELOPERS" type="fix">46545 - Fixed ObjRecord to ignore excessive padding written by previous POI versions</action>
index db973ec21b039490e2e5e1c0be345ecb47cd5f75..babedab61d13dab4465d13e6a28775649a099f52 100644 (file)
@@ -128,7 +128,7 @@ public final class Countif implements Function {
                                case NONE:
                                case EQ:
                                        return cmpResult == 0;
-                               case NE: return cmpResult == 0;
+                               case NE: return cmpResult != 0;
                                case LT: return cmpResult <  0;
                                case LE: return cmpResult <= 0;
                                case GT: return cmpResult >  0;
@@ -160,14 +160,27 @@ public final class Countif implements Function {
                        double testValue;
                        if(x instanceof StringEval) {
                                // if the target(x) is a string, but parses as a number
-                               // it may still count as a match
+                               // it may still count as a match, only for the equality operator
+                               switch (_operator.getCode()) {
+                                       case CmpOp.EQ:
+                                       case CmpOp.NONE:
+                                               break;
+                                       case CmpOp.NE:
+                                               // Always matches (inconsistent with above two cases).
+                                               // for example '<>123' matches '123', '4', 'abc', etc
+                                               return true;
+                                       default:
+                                               // never matches (also inconsistent with above three cases).
+                                               // for example '>5' does not match '6', 
+                                               return false;
+                               }
                                StringEval se = (StringEval)x;
                                Double val = OperandResolver.parseDouble(se.getStringValue());
                                if(val == null) {
                                        // x is text that is not a number
                                        return false;
                                }
-                               testValue = val.doubleValue();
+                               return _value == val.doubleValue();
                        } else if((x instanceof NumberEval)) {
                                NumberEval ne = (NumberEval) x;
                                testValue = ne.getNumberValue();
@@ -249,6 +262,7 @@ public final class Countif implements Function {
                                        _pattern = getWildCardPattern(value);
                                        break;
                                default:
+                                       // pattern matching is never used for < > <= =>
                                        _pattern = null;
                        }
                }
index 279ae51068b5b5b71228c2ce0bf3e5c767c9e63e..f11749030b1630bd615ad5ae7fab1a16e6f4e988 100755 (executable)
@@ -108,11 +108,64 @@ public final class TestCountFuncs extends TestCase {
                // note - same results when criteria is a string that parses as the number with the same value
                confirmCountIf(3, range, new StringEval("2.00"));
 
-               if (false) { // not supported yet:
-                       // when criteria is an expression (starting with a comparison operator)
-                       confirmCountIf(4, range, new StringEval(">1"));
+               // when criteria is an expression (starting with a comparison operator)
+               confirmCountIf(2, range, new StringEval(">1"));
+               // when criteria is an expression (starting with a comparison operator)
+               confirmCountIf(2, range, new StringEval(">0.5"));
+       }
+
+       public void testCriteriaPredicateNe_Bug46647() {
+               I_MatchPredicate mp = Countif.createCriteriaPredicate(new StringEval("<>aa"), 0, 0);
+               StringEval seA = new StringEval("aa"); // this should not match the criteria '<>aa'
+               StringEval seB = new StringEval("bb"); // this should match
+               if (mp.matches(seA) && !mp.matches(seB)) {
+                       throw new AssertionFailedError("Identified bug 46647");
                }
+               assertFalse(mp.matches(seA));
+               assertTrue(mp.matches(seB));
+
+               // general tests for not-equal (<>) operator
+               AreaEval range;
+               ValueEval[] values;
+
+               values = new ValueEval[] {
+                               new StringEval("aa"),
+                               new StringEval("def"),
+                               new StringEval("aa"),
+                               new StringEval("ghi"),
+                               new StringEval("aa"),
+                               new StringEval("aa"),
+               };
+
+               range = EvalFactory.createAreaEval("A1:A6", values);
+               confirmCountIf(2, range, new StringEval("<>aa"));
+
+               values = new ValueEval[] {
+                               new StringEval("ab"),
+                               new StringEval("aabb"),
+                               new StringEval("aa"), // match
+                               new StringEval("abb"),
+                               new StringEval("aab"),
+                               new StringEval("ba"), // match
+               };
+
+               range = EvalFactory.createAreaEval("A1:A6", values);
+               confirmCountIf(2, range, new StringEval("<>a*b"));
+
+
+               values = new ValueEval[] {
+                               new NumberEval(222),
+                               new NumberEval(222),
+                               new NumberEval(111),
+                               new StringEval("aa"),
+                               new StringEval("111"),
+               };
+
+               range = EvalFactory.createAreaEval("A1:A5", values);
+               confirmCountIf(4, range, new StringEval("<>111"));
+       
        }
+
        /**
         * special case where the criteria argument is a cell reference
         */
@@ -219,7 +272,7 @@ public final class TestCountFuncs extends TestCase {
                confirmPredicate(true, mp, 4);
                confirmPredicate(true, mp, 5);
                confirmPredicate(false, mp, 6);
-               confirmPredicate(true, mp, "4.9");
+               confirmPredicate(false, mp, "4.9");
                confirmPredicate(false, mp, "4.9t");
                confirmPredicate(false, mp, "5.1");
                confirmPredicate(false, mp, NULL);