]> source.dussan.org Git - poi.git/commitdiff
bug 59814: clear evaluation workbook and evaluation sheet caches. Patch from Greg...
authorJaven O'Neal <onealj@apache.org>
Thu, 7 Jul 2016 22:22:10 +0000 (22:22 +0000)
committerJaven O'Neal <onealj@apache.org>
Thu, 7 Jul 2016 22:22:10 +0000 (22:22 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1751836 13f79535-47bb-0310-9956-ffa450edef68

13 files changed:
src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationSheet.java
src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
src/java/org/apache/poi/ss/formula/EvaluationSheet.java
src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java
src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationSheet.java
src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java
src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFEvaluationSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/BaseXSSFEvaluationWorkbook.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java
src/ooxml/testcases/org/apache/poi/ss/formula/TestStructuredReferences.java
test-data/spreadsheet/StructuredReferences.xlsx

index 3497539bedf0560cfad1c49311fc90e813cc2a23..0af2c842e7fee586ea16106c780003494ee72409 100644 (file)
@@ -45,4 +45,8 @@ final class HSSFEvaluationSheet implements EvaluationSheet {
                }
                return new HSSFEvaluationCell(cell, this);
        }
+       
+       public void clearAllCachedResultValues() {
+           // nothing to do
+       }
 }
index 81eef90050969c4be65a96311c3ea3ceef494800..61984497ec4c492f1b62eed653e2616bef06c043 100644 (file)
@@ -64,6 +64,10 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
         _iBook = book.getWorkbook();
     }
     
+    public void clearAllCachedResultValues() {
+        // nothing to do
+    }
+    
     @Override
     public HSSFName createName() {
         return _uBook.createName();
index 5dec3aacda8325bbe1586e9c2533e8c1a2b25a1c..3cc292dc5463c40ad87c9284e8fbc0f70f1c465c 100644 (file)
@@ -30,4 +30,12 @@ public interface EvaluationSheet {
         * @return <code>null</code> if there is no cell at the specified coordinates
         */
        EvaluationCell getCell(int rowIndex, int columnIndex);
+       
+    /**
+     * Propagated from {@link EvaluationWorkbook#clearAllCachedResultValues()} to clear locally cached data.
+     * 
+     * @see WorkbookEvaluator#clearAllCachedResultValues()
+     * @see EvaluationWorkbook#clearAllCachedResultValues()
+     */
+    public void clearAllCachedResultValues();
 }
index b0a3c76060fcc27caa6d75ec16057ae7ba185e5c..fc4cfb32b5cf456552f9aa6e88c6ee9c45acd7c6 100644 (file)
@@ -73,6 +73,13 @@ public interface EvaluationWorkbook {
     String resolveNameXText(NameXPtg ptg);
     Ptg[] getFormulaTokens(EvaluationCell cell);
     UDFFinder getUDFFinder();
+    
+    /**
+     * Propagated from {@link WorkbookEvaluator#clearAllCachedResultValues()} to clear locally cached data.
+     * Implementations must call the same method on all referenced {@link EvaluationSheet} instances, as well as clearing local caches.
+     * @see WorkbookEvaluator#clearAllCachedResultValues()
+     */
+    public void clearAllCachedResultValues();
 
     class ExternalSheet {
         private final String _workbookName;
index d1e7d8b226454b71f5b5048c0a03e32fc2ff0dfe..4ed054467fbc3afff5d16d3a1f089eee3099a07d 100644 (file)
@@ -208,6 +208,7 @@ public final class WorkbookEvaluator {
     public void clearAllCachedResultValues() {
         _cache.clear();
         _sheetIndexesBySheet.clear();
+        _workbook.clearAllCachedResultValues();
     }
 
     /**
index 886919fe6e6b912d12b9bb3f37761b38f0df2cbb..fcf00a488b28f936b28ac668737af7c3c64b48d8 100644 (file)
@@ -101,6 +101,14 @@ final class ForkedEvaluationSheet implements EvaluationSheet {
                return mewb.getSheetIndex(_masterSheet);
        }
 
+       /* (non-Javadoc)
+        * leave the map alone, if it needs resetting, reusing this class is probably a bad idea.
+        * @see org.apache.poi.ss.formula.EvaluationSheet#clearAllCachedResultValues()
+        */
+       public void clearAllCachedResultValues() {
+           _masterSheet.clearAllCachedResultValues();
+       }
+       
        private static final class RowColKey implements Comparable<RowColKey>{
                private final int _rowIndex;
                private final int _columnIndex;
index b936a547605cfa8fd2711805eecf0fab89c1610a..5e1da9bdc9c7376338e454eb1f786e5aa57bc132 100644 (file)
@@ -136,4 +136,12 @@ final class ForkedEvaluationWorkbook implements EvaluationWorkbook {
     public UDFFinder getUDFFinder(){
         return _masterBook.getUDFFinder();
     }
+    
+    /* (non-Javadoc)
+     * leave the map alone, if it needs resetting, reusing this class is probably a bad idea.
+     * @see org.apache.poi.ss.formula.EvaluationSheet#clearAllCachedResultValues()
+     */
+    public void clearAllCachedResultValues() {
+        _masterBook.clearAllCachedResultValues();
+    }
 }
index c5d809cadaf5b5f0ea0fe1017623c24def0b6ac6..f2c11953f9a086db4301ad660f769d8cb4b7cc78 100644 (file)
@@ -47,4 +47,8 @@ final class SXSSFEvaluationSheet implements EvaluationSheet {
         }
         return new SXSSFEvaluationCell(cell, this);
     }
+    
+    public void clearAllCachedResultValues() {
+        // nothing to do
+    }
 }
index 44b182b4d7a632547897fdc924127ca892711936..8f0eac330e1be99f53e6df8844a0515ac55cff4b 100644 (file)
@@ -56,6 +56,10 @@ public abstract class BaseXSSFEvaluationWorkbook implements FormulaRenderingWork
         _uBook = book;
     }
 
+    public void clearAllCachedResultValues() {
+        _tableCache = null;
+    }
+    
     private int convertFromExternalSheetIndex(int externSheetIndex) {
         return externSheetIndex;
     }
index 0286740e08b5efe1754e48bb958eaf70a8b5a097..78aa8f86c648b00967a3991770c04f3368c66b75 100644 (file)
@@ -41,6 +41,10 @@ final class XSSFEvaluationSheet implements EvaluationSheet {
         return _xs;
     }
 
+    public void clearAllCachedResultValues() {
+        _cellCache = null;
+    }
+    
     public EvaluationCell getCell(int rowIndex, int columnIndex) {
         // cache for performance: ~30% speedup due to caching
         if (_cellCache == null) {
index 1e849b673c85904233e5a0b2275ec7f3a43e2555..60f99676cf3b3ecda9336c5fcab678c7b4b135c3 100644 (file)
@@ -40,6 +40,11 @@ public final class XSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook {
         super(book);
     }
 
+    public void clearAllCachedResultValues() {
+        super.clearAllCachedResultValues();
+        _sheetCache = null;
+    }
+    
     @Override
     public int getSheetIndex(EvaluationSheet evalSheet) {
         XSSFSheet sheet = ((XSSFEvaluationSheet)evalSheet).getXSSFSheet();
index fd598a479b300d71992e52701bd2bda4e19c2fec..4e176257f6eeeaf52895e70e1dcfbde138e5c232 100644 (file)
 package org.apache.poi.ss.formula;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellType;
 import org.apache.poi.ss.usermodel.CellValue;
 import org.apache.poi.ss.usermodel.FormulaEvaluator;
+import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Table;
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFTable;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.junit.Test;
 
@@ -63,8 +68,40 @@ public class TestStructuredReferences {
         try {
             
             final FormulaEvaluator eval = new XSSFFormulaEvaluator(wb);
-            confirm(eval, wb.getSheet("Table").getRow(5).getCell(0), 49);
-            confirm(eval, wb.getSheet("Formulas").getRow(0).getCell(0), 209);
+            final XSSFSheet tableSheet = wb.getSheet("Table");
+            final XSSFSheet formulaSheet = wb.getSheet("Formulas");
+
+            confirm(eval, tableSheet.getRow(5).getCell(0), 49);
+            confirm(eval, formulaSheet.getRow(0).getCell(0), 209);
+            confirm(eval, formulaSheet.getRow(1).getCell(0), "one");
+            
+            // test changing a table value, to see if the caches are properly cleared
+            // Issue 59814
+            
+            // this test passes before the fix for 59814
+            tableSheet.getRow(1).getCell(1).setCellValue("ONEA");
+            confirm(eval, formulaSheet.getRow(1).getCell(0), "ONEA");
+            
+            // test adding a row to a table, issue 59814
+            Row newRow = tableSheet.getRow(7);
+            if (newRow == null) newRow = tableSheet.createRow(7);
+            newRow.createCell(0, CellType.FORMULA).setCellFormula("\\_Prime.1[[#This Row],[@Number]]*\\_Prime.1[[#This Row],[@Number]]");
+            newRow.createCell(1, CellType.STRING).setCellValue("thirteen");
+            newRow.createCell(2, CellType.NUMERIC).setCellValue(13);
+            
+            // update Table
+            final XSSFTable table = wb.getTable("\\_Prime.1");
+            final AreaReference newArea = new AreaReference(table.getStartCellReference(), new CellReference(table.getEndRowIndex() + 1, table.getEndColIndex()));
+            String newAreaStr = newArea.formatAsString();
+            table.getCTTable().setRef(newAreaStr);
+            table.getCTTable().getAutoFilter().setRef(newAreaStr);
+            table.updateHeaders();
+            table.updateReferences();
+
+            // these fail before the fix for 59814
+            confirm(eval, tableSheet.getRow(7).getCell(0), 13*13);
+            confirm(eval, formulaSheet.getRow(0).getCell(0), 209 + 13*13);
+
         } finally {
             wb.close();
         }
@@ -78,4 +115,13 @@ public class TestStructuredReferences {
         }
         assertEquals(expectedResult, cv.getNumberValue(), 0.0);
     }
+
+    private static void confirm(FormulaEvaluator fe, Cell cell, String expectedResult) {
+        fe.clearAllCachedResultValues();
+        CellValue cv = fe.evaluate(cell);
+        if (cv.getCellType() != CellType.STRING) {
+            fail("expected String cell type but got " + cv.formatAsString());
+        }
+        assertEquals(expectedResult, cv.getStringValue());
+    }
 }
index 54cf75234eebdcb10af2db597f9e49b8ccc8db53..90a470a93f0934c29c73970759323864b66d3073 100644 (file)
Binary files a/test-data/spreadsheet/StructuredReferences.xlsx and b/test-data/spreadsheet/StructuredReferences.xlsx differ