summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2018-02-08 22:48:56 +0100
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2018-02-26 11:42:44 +0100
commited2a66a2ccace13c3d85490300cd623109214b0e (patch)
tree07c461f115917eb6f0f3fe65bb56e023976af8d0
parenta16ecbb7a23ef639e3a164383e777ee0eccb399b (diff)
Resolves: tdf#115493 use matrix as result of jump command, tdf#58874 related
{=SUM(IF(EXACT(OFFSET(A7,0,0):OFFSET(A7,2,0),A$1),OFFSET(A7,0,1):OFFSET(A7,2,1),0))} shall be the same as {=SUM(IF(EXACT(A7:A9,A$1),B7:B9,0))} Change-Id: Id503ef41140d1e9c4aeabbec08d1199dd6dd8593 (cherry picked from commit e0a94ded5d1635fa2a2d9e222bfcfa0a2289a01f) Reviewed-on: https://gerrit.libreoffice.org/49464 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r--sc/source/core/inc/jumpmatrix.hxx4
-rw-r--r--sc/source/core/tool/interpr1.cxx16
-rw-r--r--sc/source/core/tool/interpr4.cxx2
-rw-r--r--sc/source/core/tool/jumpmatrix.cxx3
4 files changed, 17 insertions, 8 deletions
diff --git a/sc/source/core/inc/jumpmatrix.hxx b/sc/source/core/inc/jumpmatrix.hxx
index cbc1a1d0671c..084f5a91f4bb 100644
--- a/sc/source/core/inc/jumpmatrix.hxx
+++ b/sc/source/core/inc/jumpmatrix.hxx
@@ -67,6 +67,7 @@ class ScJumpMatrix
SCSIZE nCurRow;
SCSIZE nResMatCols;
SCSIZE nResMatRows;
+ OpCode meOp;
bool bStarted;
// Buffer result ranges to be able to set a range of identically typed
@@ -96,7 +97,7 @@ class ScJumpMatrix
ScJumpMatrix& operator=( const ScJumpMatrix& ) = delete;
public:
- ScJumpMatrix( SCSIZE nColsP, SCSIZE nRowsP );
+ ScJumpMatrix( OpCode eOp, SCSIZE nColsP, SCSIZE nRowsP );
~ScJumpMatrix();
void GetDimensions( SCSIZE& rCols, SCSIZE& rRows ) const;
void SetJump( SCSIZE nCol, SCSIZE nRow, double fBool, short nStart, short nNext );
@@ -111,6 +112,7 @@ public:
void GetResMatDimensions( SCSIZE& rCols, SCSIZE& rRows );
void SetNewResMat( SCSIZE nNewCols, SCSIZE nNewRows );
ScRefList& GetRefList();
+ OpCode GetOpCode() const { return meOp; }
void PutResultDouble( double fVal, SCSIZE nC, SCSIZE nR );
void PutResultString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR );
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index e59b46c9f42f..ca588b6a9f03 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -110,7 +110,8 @@ void ScInterpreter::ScIfJump()
xNew = (*aMapIter).second;
else
{
- std::shared_ptr<ScJumpMatrix> pJumpMat( std::make_shared<ScJumpMatrix>( nCols, nRows ) );
+ std::shared_ptr<ScJumpMatrix> pJumpMat( std::make_shared<ScJumpMatrix>(
+ pCur->GetOpCode(), nCols, nRows));
for ( SCSIZE nC=0; nC < nCols; ++nC )
{
for ( SCSIZE nR=0; nR < nRows; ++nR )
@@ -339,7 +340,8 @@ void ScInterpreter::ScIfError( bool bNAonly )
else
{
const ScMatrix* pMatPtr = pMat.get();
- std::shared_ptr<ScJumpMatrix> pJumpMat( std::make_shared<ScJumpMatrix>( nCols, nRows ) );
+ std::shared_ptr<ScJumpMatrix> pJumpMat( std::make_shared<ScJumpMatrix>(
+ pCur->GetOpCode(), nCols, nRows));
// Init all jumps to no error to save single calls. Error
// is the exceptional condition.
const double fFlagResult = CreateDoubleError( FormulaError::JumpMatHasResult);
@@ -430,7 +432,8 @@ void ScInterpreter::ScChooseJump()
xNew = (*aMapIter).second;
else
{
- std::shared_ptr<ScJumpMatrix> pJumpMat( std::make_shared<ScJumpMatrix>( nCols, nRows ) );
+ std::shared_ptr<ScJumpMatrix> pJumpMat( std::make_shared<ScJumpMatrix>(
+ pCur->GetOpCode(), nCols, nRows));
for ( SCSIZE nC=0; nC < nCols; ++nC )
{
for ( SCSIZE nR=0; nR < nRows; ++nR )
@@ -799,8 +802,11 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
{ // We're done with it, throw away jump matrix, keep result.
// For an intermediate result of Reference use the array of references,
// else (also for a final result of Reference) use the matrix.
- formula::ParamClass eReturnType = ScParameterClassification::GetParameterType( pCur, SAL_MAX_UINT16);
- if (eReturnType == ParamClass::Reference && aCode.PeekNextOperator())
+ // Treat the result of a jump command as final and use the matrix (see
+ // tdf#115493 for why).
+ if (!FormulaCompiler::IsOpCodeJumpCommand( pJumpMatrix->GetOpCode()) &&
+ ScParameterClassification::GetParameterType( pCur, SAL_MAX_UINT16) == ParamClass::Reference &&
+ aCode.PeekNextOperator())
{
FormulaTokenRef xRef = new ScRefListToken(true);
*(xRef->GetRefList()) = pJumpMatrix->GetRefList();
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index f80afe2bd5a8..904fecd66f86 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1580,7 +1580,7 @@ bool ScInterpreter::ConvertMatrixParameters()
xNew = (*aMapIter).second;
else
{
- std::unique_ptr<ScJumpMatrix> pJumpMat( new ScJumpMatrix( nJumpCols, nJumpRows) );
+ std::unique_ptr<ScJumpMatrix> pJumpMat( new ScJumpMatrix( pCur->GetOpCode(), nJumpCols, nJumpRows));
pJumpMat->SetAllJumps( 1.0, nStart, nNext, nStop);
// pop parameters and store in ScJumpMatrix, push in JumpMatrix()
ScTokenVec* pParams = new ScTokenVec( nParams);
diff --git a/sc/source/core/tool/jumpmatrix.cxx b/sc/source/core/tool/jumpmatrix.cxx
index c80c8ca1cf0d..c0795e88e0c1 100644
--- a/sc/source/core/tool/jumpmatrix.cxx
+++ b/sc/source/core/tool/jumpmatrix.cxx
@@ -27,7 +27,7 @@ namespace {
const SCSIZE kBufferThreshold = 128;
}
-ScJumpMatrix::ScJumpMatrix(SCSIZE nColsP, SCSIZE nRowsP)
+ScJumpMatrix::ScJumpMatrix( OpCode eOp, SCSIZE nColsP, SCSIZE nRowsP )
: mvJump(nColsP * nRowsP)
, pMat(new ScFullMatrix(nColsP, nRowsP))
, pParams(nullptr)
@@ -37,6 +37,7 @@ ScJumpMatrix::ScJumpMatrix(SCSIZE nColsP, SCSIZE nRowsP)
, nCurRow(0)
, nResMatCols(nColsP)
, nResMatRows(nRowsP)
+ , meOp(eOp)
, bStarted(false)
, mnBufferCol(0)
, mnBufferRowStart(0)