poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r891468 - in /poi/trunk/src: java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java java/org/apache/poi/ss/formula/WorkbookEvaluator.java testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java
Date Wed, 16 Dec 2009 23:16:30 GMT
Author: josh
Date: Wed Dec 16 23:16:30 2009
New Revision: 891468

URL: http://svn.apache.org/viewvc?rev=891468&view=rev
Log:
fixed special cases of dereferenceResult method

Modified:
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java
    poi/trunk/src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
    poi/trunk/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java?rev=891468&r1=891467&r2=891468&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java Wed Dec
16 23:16:30 2009
@@ -103,14 +103,8 @@
 	public static ValueEval chooseSingleElementFromArea(AreaEval ae,
 			int srcCellRow, int srcCellCol) throws EvaluationException {
 		ValueEval result = chooseSingleElementFromAreaInternal(ae, srcCellRow, srcCellCol);
-		if(result == null) {
-			// This seems to be required because AreaEval.values() array may contain nulls.
-			// perhaps that should not be allowed.
-			result = BlankEval.instance;
-		}
 		if (result instanceof ErrorEval) {
 			throw new EvaluationException((ErrorEval) result);
-
 		}
 		return result;
 	}

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=891468&r1=891467&r2=891468&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 Wed Dec 16 23:16:30
2009
@@ -57,6 +57,7 @@
 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;
+import org.apache.poi.hssf.record.formula.eval.OperandResolver;
 import org.apache.poi.hssf.record.formula.eval.RefEval;
 import org.apache.poi.hssf.record.formula.eval.StringEval;
 import org.apache.poi.hssf.record.formula.eval.ValueEval;
@@ -449,14 +450,7 @@
 		if (!stack.isEmpty()) {
 			throw new IllegalStateException("evaluation stack not empty");
 		}
-		value = dereferenceValue(value, ec.getRowIndex(), ec.getColumnIndex());
-		if (value == BlankEval.instance) {
-			// Note Excel behaviour here. A blank final final value is converted to zero.
-			return NumberEval.ZERO;
-			// Formulas _never_ evaluate to blank.  If a formula appears to have evaluated to
-			// blank, the actual value is empty string. This can be verified with ISBLANK().
-		}
-		return value;
+		return dereferenceResult(value, ec.getRowIndex(), ec.getColumnIndex());
 	}
 
 	/**
@@ -480,31 +474,30 @@
 		}
 		return index-startIndex;
 	}
+
 	/**
-	 * Dereferences a single value from any AreaEval or RefEval evaluation result.
-	 * If the supplied evaluationResult is just a plain value, it is returned as-is.
-	 * @return a <tt>NumberEval</tt>, <tt>StringEval</tt>, <tt>BoolEval</tt>,
-	 *  <tt>BlankEval</tt> or <tt>ErrorEval</tt>. Never <code>null</code>.
-	 */
-	private static ValueEval dereferenceValue(ValueEval evaluationResult, int srcRowNum, int
srcColNum) {
-		if (evaluationResult instanceof RefEval) {
-			RefEval rv = (RefEval) evaluationResult;
-			return rv.getInnerValueEval();
-		}
-		if (evaluationResult instanceof AreaEval) {
-			AreaEval ae = (AreaEval) evaluationResult;
-			if (ae.isRow()) {
-				if(ae.isColumn()) {
-					return ae.getRelativeValue(0, 0);
-				}
-				return ae.getAbsoluteValue(ae.getFirstRow(), srcColNum);
-			}
-			if (ae.isColumn()) {
-				return ae.getAbsoluteValue(srcRowNum, ae.getFirstColumn());
-			}
-			return ErrorEval.VALUE_INVALID;
+	 * Dereferences a single value from any AreaEval or RefEval evaluation
+	 * result. If the supplied evaluationResult is just a plain value, it is
+	 * returned as-is.
+	 *
+	 * @return a {@link NumberEval}, {@link StringEval}, {@link BoolEval}, or
+	 *         {@link ErrorEval}. Never <code>null</code>. {@link BlankEval} is
+	 *         converted to {@link NumberEval#ZERO}
+	 */
+	public static ValueEval dereferenceResult(ValueEval evaluationResult, int srcRowNum, int
srcColNum) {
+		ValueEval value;
+		try {
+			value = OperandResolver.getSingleValue(evaluationResult, srcRowNum, srcColNum);
+		} catch (EvaluationException e) {
+			return e.getErrorEval();
+		}
+		if (value == BlankEval.instance) {
+			// Note Excel behaviour here. A blank final final value is converted to zero.
+			return NumberEval.ZERO;
+			// Formulas _never_ evaluate to blank.  If a formula appears to have evaluated to
+			// blank, the actual value is empty string. This can be verified with ISBLANK().
 		}
-		return evaluationResult;
+		return value;
 	}
 
 

Modified: poi/trunk/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java?rev=891468&r1=891467&r2=891468&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/ss/formula/TestWorkbookEvaluator.java Wed Dec 16
23:16:30 2009
@@ -38,7 +38,11 @@
 import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellValue;
+import org.apache.poi.ss.usermodel.ErrorConstants;
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
+import org.apache.poi.ss.usermodel.Workbook;
 
 /**
  * Tests {@link WorkbookEvaluator}.
@@ -193,7 +197,7 @@
 		assertEquals(HSSFCell.CELL_TYPE_STRING, cv.getCellType());
 		// adding blank to "abc" gives "abc"
 		assertEquals("abc", cv.getStringValue());
-		
+
 		// check CHOOSE()
 		cell.setCellFormula("\"abc\"&CHOOSE(2,5,,9)");
 		fe.notifySetFormula(cell);
@@ -202,4 +206,33 @@
 		// adding blank to "abc" gives "abc"
 		assertEquals("abc", cv.getStringValue());
 	}
+
+	/**
+	 * Functions like IF, INDIRECT, INDEX, OFFSET etc can return AreaEvals which
+	 * should be dereferenced by the evaluator
+	 */
+	public void testResultOutsideRange() {
+		Workbook wb = new HSSFWorkbook();
+		Cell cell = wb.createSheet("Sheet1").createRow(0).createCell(0);
+		cell.setCellFormula("D2:D5"); // IF(TRUE,D2:D5,D2) or  OFFSET(D2:D5,0,0) would work too
+		FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
+		CellValue cv;
+		try {
+			cv = fe.evaluate(cell);
+		} catch (IllegalArgumentException e) {
+			if ("Specified row index (0) is outside the allowed range (1..4)".equals(e.getMessage()))
{
+				throw new AssertionFailedError("Identified bug in result dereferencing");
+			}
+			throw new RuntimeException(e);
+		}
+		assertEquals(Cell.CELL_TYPE_ERROR, cv.getCellType());
+		assertEquals(ErrorConstants.ERROR_VALUE, cv.getErrorValue());
+
+		// verify circular refs are still detected properly
+		fe.clearAllCachedResultValues();
+		cell.setCellFormula("OFFSET(A1,0,0)");
+		cv = fe.evaluate(cell);
+		assertEquals(Cell.CELL_TYPE_ERROR, cv.getCellType());
+		assertEquals(ErrorEval.CIRCULAR_REF_ERROR.getErrorCode(), cv.getErrorValue());
+	}
 }



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


Mime
View raw message