Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/1756

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/56/1756/1

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
---
M dbaccess/source/ui/querydesign/QueryDesignView.cxx
1 file changed, 33 insertions(+), 18 deletions(-)



diff --git a/dbaccess/source/ui/querydesign/QueryDesignView.cxx 
b/dbaccess/source/ui/querydesign/QueryDesignView.cxx
index 816991a..3c386db 100644
--- a/dbaccess/source/ui/querydesign/QueryDesignView.cxx
+++ b/dbaccess/source/ui/querydesign/QueryDesignView.cxx
@@ -476,10 +476,29 @@
         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<OQueryTableWindow*>(pEntryConn->GetSourceWin());
+            const OQueryTableWindow* const pEntryTabTo = 
static_cast<OQueryTableWindow*>(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<OQueryTableConnectionData*>(pEntryConn->GetData().get());
         if ( pEntryConnData->GetJoinType() == INNER_JOIN && 
!pEntryConnData->isNatural() )
@@ -487,15 +506,18 @@
 
         if(aJoin.isEmpty())
         {
+            addConnectionTableNames(_xConnection, pEntryConn, _rTableNames);
             OQueryTableWindow* pEntryTabFrom = 
static_cast<OQueryTableWindow*>(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 @@
                 // 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 @@
                     // 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 @@
     
//------------------------------------------------------------------------------
     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 @@
     {
 
         ::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 @@
                     if(!pEntryConn->IsVisited() && pEntryConn->GetSourceWin() 
== aRIter->second )
                     {
                         ::rtl::OUString aJoin;
-                        
GetNextJoin(_xConnection,pEntryConn,static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),aJoin);
+                        GetNextJoin(_xConnection,
+                                    pEntryConn,
+                                    
static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),
+                                    aJoin,
+                                    aTableNames);
 
                         if(!aJoin.isEmpty())
                         {
-                            // insert tables into table list to avoid double 
entries
-                            OQueryTableWindow* pEntryTabFrom = 
static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin());
-                            OQueryTableWindow* pEntryTabTo = 
static_cast<OQueryTableWindow*>(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<OQueryTableConnectionData*>(pEntryConn->GetData().get())->GetJoinType())
                             {

-- 
To view, visit https://gerrit.libreoffice.org/1756
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I03e0f0ef51f45be9d7ddfa63a9dbe09dc500f8dd
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-4-0
Gerrit-Owner: Lionel Elie Mamane <lio...@mamane.lu>

_______________________________________________
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice

Reply via email to