diff options
author | Eike Rathke <erack@redhat.com> | 2018-02-08 22:48:56 +0100 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2018-02-26 11:42:44 +0100 |
commit | ed2a66a2ccace13c3d85490300cd623109214b0e (patch) | |
tree | 07c461f115917eb6f0f3fe65bb56e023976af8d0 | |
parent | a16ecbb7a23ef639e3a164383e777ee0eccb399b (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.hxx | 4 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 16 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/jumpmatrix.cxx | 3 |
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) |