You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jo...@apache.org on 2008/10/06 21:13:42 UTC

svn commit: r702231 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/hssf/record/formula/eval/ java/org/apache/poi/hssf/record/formula/functions/ java/org/apache/poi/ss/formula/ testcases/org/apache/poi/hssf/record/formula/eval/

Author: josh
Date: Mon Oct  6 12:13:41 2008
New Revision: 702231

URL: http://svn.apache.org/viewvc?rev=702231&view=rev
Log:
Fix for 43354 - made the formula evaluator capable of handling missing function arguments

Added:
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/MissingArgEval.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestMissingArgEval.java
Modified:
    poi/trunk/src/documentation/content/xdocs/changes.xml
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/Count.java
    poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
    poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java

Modified: poi/trunk/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/changes.xml?rev=702231&r1=702230&r2=702231&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/changes.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/changes.xml Mon Oct  6 12:13:41 2008
@@ -37,6 +37,7 @@
 
 		<!-- Don't forget to update status.xml too! -->
         <release version="3.2-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">43354 - support for evalating formulas with missing args</action>
            <action dev="POI-DEVELOPERS" type="fix">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
            <action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </action>
            <action dev="POI-DEVELOPERS" type="add">Initial support for creating hyperlinks in HSLF</action>

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=702231&r1=702230&r2=702231&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Mon Oct  6 12:13:41 2008
@@ -34,6 +34,7 @@
 	<!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.2-alpha1" date="2008-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">43354 - support for evalating formulas with missing args</action>
            <action dev="POI-DEVELOPERS" type="fix">45912 - fixed ArrayIndexOutOfBoundsException in EmbeddedObjectRefSubRecord</action>
            <action dev="POI-DEVELOPERS" type="fix">45889 - fixed ArrayIndexOutOfBoundsException when constructing HSLF Table with a single row </action>
            <action dev="POI-DEVELOPERS" type="add">Initial support for creating hyperlinks in HSLF</action>

Added: poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/MissingArgEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/MissingArgEval.java?rev=702231&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/MissingArgEval.java (added)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/MissingArgEval.java Mon Oct  6 12:13:41 2008
@@ -0,0 +1,35 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.eval;
+
+/**
+ * Represents the (intermediate) evaluated result of a missing function argument.  In most cases
+ * this can be translated into {@link BlankEval} but there are some notable exceptions.  Functions
+ * COUNT and COUNTA <em>do</em> count their missing args.  Note - the differences between 
+ * {@link MissingArgEval} and {@link BlankEval} have not been investigated fully, so the POI
+ * evaluator may need to be updated to account for these as they are found.
+ *
+ * @author Josh Micich
+ */
+public final class MissingArgEval implements ValueEval {
+
+    public static MissingArgEval instance = new MissingArgEval();
+
+    private MissingArgEval() {
+    }
+}

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/Count.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/Count.java?rev=702231&r1=702230&r2=702231&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/Count.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/functions/Count.java Mon Oct  6 12:13:41 2008
@@ -19,6 +19,7 @@
 
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
+import org.apache.poi.hssf.record.formula.eval.MissingArgEval;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
 import org.apache.poi.hssf.record.formula.functions.CountUtils.I_MatchPredicate;
 
@@ -64,6 +65,10 @@
 				// only numbers are counted
 				return true;
 			}
+			if(valueEval == MissingArgEval.instance) {
+				// oh yeah, and missing arguments
+				return true;
+			}
 
 			// error values and string values not counted
 			return false;

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java?rev=702231&r1=702230&r2=702231&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java Mon Oct  6 12:13:41 2008
@@ -52,6 +52,7 @@
 import org.apache.poi.hssf.record.formula.eval.ErrorEval;
 import org.apache.poi.hssf.record.formula.eval.Eval;
 import org.apache.poi.hssf.record.formula.eval.FunctionEval;
+import org.apache.poi.hssf.record.formula.eval.MissingArgEval;
 import org.apache.poi.hssf.record.formula.eval.NameEval;
 import org.apache.poi.hssf.record.formula.eval.NameXEval;
 import org.apache.poi.hssf.record.formula.eval.NumberEval;
@@ -284,10 +285,7 @@
 				continue;
 			}
 			if (ptg instanceof MemErrPtg) { continue; }
-			if (ptg instanceof MissingArgPtg) {
-				// TODO - might need to push BlankEval or MissingArgEval
-				continue;
-			}
+
 			Eval opResult;
 			if (ptg instanceof OperationPtg) {
 				OperationPtg optg = (OperationPtg) ptg;
@@ -306,6 +304,9 @@
 				}
 //				logDebug("invoke " + operation + " (nAgs=" + numops + ")");
 				opResult = invokeOperation(operation, ops, _workbook, sheetIndex, srcRowNum, srcColNum);
+				if (opResult == MissingArgEval.instance) {
+					opResult = BlankEval.INSTANCE;
+				}
 			} else {
 				opResult = getEvalForPtg(ptg, sheetIndex, tracker);
 			}
@@ -424,6 +425,9 @@
 		if (ptg instanceof ErrPtg) {
 			return ErrorEval.valueOf(((ErrPtg) ptg).getErrorCode());
 		}
+		if (ptg instanceof MissingArgPtg) {
+			return MissingArgEval.instance;
+		}
 		if (ptg instanceof AreaErrPtg ||ptg instanceof RefErrorPtg 
 				|| ptg instanceof DeletedArea3DPtg || ptg instanceof DeletedRef3DPtg) {
 				return ErrorEval.REF_INVALID;

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java?rev=702231&r1=702230&r2=702231&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/AllFormulaEvalTests.java Mon Oct  6 12:13:41 2008
@@ -36,6 +36,7 @@
 		result.addTestSuite(TestExternalFunction.class);
 		result.addTestSuite(TestFormulaBugs.class);
 		result.addTestSuite(TestFormulasFromSpreadsheet.class);
+		result.addTestSuite(TestMissingArgEval.class);
 		result.addTestSuite(TestPercentEval.class);
 		result.addTestSuite(TestRangeEval.class);
 		result.addTestSuite(TestUnaryPlusEval.class);

Added: poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestMissingArgEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestMissingArgEval.java?rev=702231&view=auto
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestMissingArgEval.java (added)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestMissingArgEval.java Mon Oct  6 12:13:41 2008
@@ -0,0 +1,74 @@
+/* ====================================================================
+   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.poi.hssf.record.formula.eval;
+
+import java.util.EmptyStackException;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue;
+
+/**
+ * Tests for {@link MissingArgEval}
+ *
+ * @author Josh Micich
+ */
+public final class TestMissingArgEval extends TestCase {
+	
+	public void testEvaluateMissingArgs() {
+		HSSFWorkbook wb = new HSSFWorkbook();
+		HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+		HSSFSheet sheet = wb.createSheet("Sheet1");
+		HSSFCell cell = sheet.createRow(0).createCell(0);
+		
+		cell.setCellFormula("if(true,)"); 
+		fe.clearAllCachedResultValues();
+		CellValue cv;
+		try {
+			cv = fe.evaluate(cell);
+		} catch (EmptyStackException e) {
+			throw new AssertionFailedError("Missing args evaluation not implemented (bug 43354");
+		}
+		// MissingArg -> BlankEval -> zero (as formula result)
+		assertEquals(0.0, cv.getNumberValue(), 0.0);
+		
+		// MissingArg -> BlankEval -> empty string (in concatenation)
+		cell.setCellFormula("\"abc\"&if(true,)"); 
+		fe.clearAllCachedResultValues();
+		assertEquals("abc", fe.evaluate(cell).getStringValue());
+	}
+	
+	public void testCountFuncs() {
+		HSSFWorkbook wb = new HSSFWorkbook();
+		HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+		HSSFSheet sheet = wb.createSheet("Sheet1");
+		HSSFCell cell = sheet.createRow(0).createCell(0);
+		
+		cell.setCellFormula("COUNT(C5,,,,)"); // 4 missing args, C5 is blank 
+		assertEquals(4.0, fe.evaluate(cell).getNumberValue(), 0.0);
+
+		cell.setCellFormula("COUNTA(C5,,)"); // 2 missing args, C5 is blank 
+		fe.clearAllCachedResultValues();
+		assertEquals(2.0, fe.evaluate(cell).getNumberValue(), 0.0);
+	}
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org