From 8f766122f0c5fbbb5442e1a5dd6f4eab9744d5cd Mon Sep 17 00:00:00 2001 From: Lionel Elie Mamane Date: Fri, 18 Jan 2013 18:44:22 +0100 Subject: mark *all* tables of a nested join as added Else, if the n^{th} (with n>2) table also appears in a (non-NATURAL) INNER JOIN, it is repeated later, leading to an error from the database engine Change-Id: I03e0f0ef51f45be9d7ddfa63a9dbe09dc500f8dd --- dbaccess/source/ui/querydesign/QueryDesignView.cxx | 51 ++++++++++++++-------- 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'dbaccess') diff --git a/dbaccess/source/ui/querydesign/QueryDesignView.cxx b/dbaccess/source/ui/querydesign/QueryDesignView.cxx index 9ef92b948ed9..5507634aa320 100644 --- a/dbaccess/source/ui/querydesign/QueryDesignView.cxx +++ b/dbaccess/source/ui/querydesign/QueryDesignView.cxx @@ -476,10 +476,29 @@ namespace return BuildJoin(_xConnection, rRh, BuildTable(_xConnection,pLh), &data); } //------------------------------------------------------------------------------ + typedef ::std::map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess> tableNames_t; + //------------------------------------------------------------------------------ + void addConnectionTableNames( const Reference< XConnection>& _xConnection, + const OQueryTableConnection* const pEntryConn, + tableNames_t &_rTableNames ) + { + // insert tables into table list to avoid double entries + const OQueryTableWindow* const pEntryTabFrom = static_cast(pEntryConn->GetSourceWin()); + const OQueryTableWindow* const pEntryTabTo = static_cast(pEntryConn->GetDestWin()); + + ::rtl::OUString sTabName(BuildTable(_xConnection,pEntryTabFrom)); + if(_rTableNames.find(sTabName) == _rTableNames.end()) + _rTableNames[sTabName] = sal_True; + sTabName = BuildTable(_xConnection,pEntryTabTo); + if(_rTableNames.find(sTabName) == _rTableNames.end()) + _rTableNames[sTabName] = sal_True; + } + //------------------------------------------------------------------------------ void GetNextJoin( const Reference< XConnection>& _xConnection, OQueryTableConnection* pEntryConn, OQueryTableWindow* pEntryTabTo, - ::rtl::OUString &aJoin) + ::rtl::OUString &aJoin, + tableNames_t &_rTableNames) { OQueryTableConnectionData* pEntryConnData = static_cast(pEntryConn->GetData().get()); if ( pEntryConnData->GetJoinType() == INNER_JOIN && !pEntryConnData->isNatural() ) @@ -487,15 +506,18 @@ namespace if(aJoin.isEmpty()) { + addConnectionTableNames(_xConnection, pEntryConn, _rTableNames); OQueryTableWindow* pEntryTabFrom = static_cast(pEntryConn->GetSourceWin()); aJoin = BuildJoin(_xConnection,pEntryTabFrom,pEntryTabTo,pEntryConnData); } else if(pEntryTabTo == pEntryConn->GetDestWin()) { + addConnectionTableNames(_xConnection, pEntryConn, _rTableNames); aJoin = BuildJoin(_xConnection,aJoin,pEntryTabTo,pEntryConnData); } else if(pEntryTabTo == pEntryConn->GetSourceWin()) { + addConnectionTableNames(_xConnection, pEntryConn, _rTableNames); aJoin = BuildJoin(_xConnection,pEntryTabTo,aJoin,pEntryConnData); } @@ -514,7 +536,7 @@ namespace // exists there a connection to a OQueryTableWindow that holds a connection that has been already visited JoinCycle(_xConnection,pNext,pEntryTab,aJoin); if(!pNext->IsVisited()) - GetNextJoin(_xConnection,pNext,pEntryTab,aJoin); + GetNextJoin(_xConnection, pNext, pEntryTab, aJoin, _rTableNames); } } @@ -532,7 +554,7 @@ namespace // exists there a connection to a OQueryTableWindow that holds a connection that has been already visited JoinCycle(_xConnection,pNext,pEntryTab,aJoin); if(!pNext->IsVisited()) - GetNextJoin(_xConnection,pNext,pEntryTab,aJoin); + GetNextJoin(_xConnection, pNext, pEntryTab, aJoin, _rTableNames); } } } @@ -1014,7 +1036,7 @@ namespace //------------------------------------------------------------------------------ void searchAndAppendName(const Reference< XConnection>& _xConnection, const OQueryTableWindow* _pTableWindow, - ::std::map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess>& _rTableNames, + tableNames_t& _rTableNames, ::rtl::OUString& _rsTableListStr ) { @@ -1035,8 +1057,8 @@ namespace { ::rtl::OUString aTableListStr; - // wird gebraucht um sicher zustelllen das eine Tabelle nicht doppelt vorkommt - ::std::map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess> aTableNames; + // used to avoid putting a table twice in FROM clause + tableNames_t aTableNames; // generate outer join clause in from if(!pConnList->empty()) @@ -1070,21 +1092,14 @@ namespace if(!pEntryConn->IsVisited() && pEntryConn->GetSourceWin() == aRIter->second ) { ::rtl::OUString aJoin; - GetNextJoin(_xConnection,pEntryConn,static_cast(pEntryConn->GetDestWin()),aJoin); + GetNextJoin(_xConnection, + pEntryConn, + static_cast(pEntryConn->GetDestWin()), + aJoin, + aTableNames); if(!aJoin.isEmpty()) { - // insert tables into table list to avoid double entries - OQueryTableWindow* pEntryTabFrom = static_cast(pEntryConn->GetSourceWin()); - OQueryTableWindow* pEntryTabTo = static_cast(pEntryConn->GetDestWin()); - - ::rtl::OUString sTabName(BuildTable(_xConnection,pEntryTabFrom)); - if(aTableNames.find(sTabName) == aTableNames.end()) - aTableNames[sTabName] = sal_True; - sTabName = BuildTable(_xConnection,pEntryTabTo); - if(aTableNames.find(sTabName) == aTableNames.end()) - aTableNames[sTabName] = sal_True; - ::rtl::OUString aStr; switch(static_cast(pEntryConn->GetData().get())->GetJoinType()) { -- cgit