LCOV - code coverage report
Current view: top level - libreoffice/dbaccess/source/ui/querydesign - QueryDesignView.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 1780 0.0 %
Date: 2012-12-17 Functions: 0 82 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "QueryDesignView.hxx"
      21             : #include "QueryTableView.hxx"
      22             : #include "QTableWindow.hxx"
      23             : #include <vcl/toolbox.hxx>
      24             : #include "querycontroller.hxx"
      25             : #include <vcl/split.hxx>
      26             : #include <svl/undo.hxx>
      27             : #include <tools/diagnose_ex.h>
      28             : #include <osl/diagnose.h>
      29             : #include "adtabdlg.hxx"
      30             : #include <vcl/svapp.hxx>
      31             : #include <vcl/combobox.hxx>
      32             : #include <vcl/msgbox.hxx>
      33             : #include "browserids.hxx"
      34             : #include "SelectionBrowseBox.hxx"
      35             : #include "dbu_qry.hrc"
      36             : #include <unotools/configmgr.hxx>
      37             : #include <comphelper/extract.hxx>
      38             : #include <comphelper/string.hxx>
      39             : #include <comphelper/types.hxx>
      40             : #include <connectivity/dbtools.hxx>
      41             : #include <connectivity/dbexception.hxx>
      42             : #include <com/sun/star/i18n/XLocaleData.hpp>
      43             : #include <com/sun/star/sdbc/DataType.hpp>
      44             : #include <com/sun/star/container/XNameAccess.hpp>
      45             : #include <com/sun/star/sdbc/ColumnValue.hpp>
      46             : #include <connectivity/PColumn.hxx>
      47             : #include "QTableConnection.hxx"
      48             : #include "ConnectionLine.hxx"
      49             : #include "ConnectionLineData.hxx"
      50             : #include "QTableConnectionData.hxx"
      51             : #include "dbustrings.hrc"
      52             : #include "UITools.hxx"
      53             : #include "querycontainerwindow.hxx"
      54             : #include "sqlmessage.hxx"
      55             : #include <unotools/syslocale.hxx>
      56             : 
      57             : using namespace ::dbaui;
      58             : using namespace ::utl;
      59             : using namespace ::connectivity;
      60             : using namespace ::dbtools;
      61             : using namespace ::com::sun::star::uno;
      62             : using namespace ::com::sun::star::lang;
      63             : using namespace ::com::sun::star::i18n;
      64             : using namespace ::com::sun::star::sdbc;
      65             : using namespace ::com::sun::star::beans;
      66             : using namespace ::com::sun::star::container;
      67             : 
      68             : // here we define our functions used in the anonymous namespace to get our header file smaller
      69             : // please look at the book LargeScale C++ to know why
      70             : namespace
      71             : {
      72           0 :     static const ::rtl::OUString C_AND(RTL_CONSTASCII_USTRINGPARAM(" AND "));
      73           0 :     static const ::rtl::OUString C_OR(RTL_CONSTASCII_USTRINGPARAM(" OR "));
      74             : 
      75             :     // forward declarations
      76             :     sal_Bool InsertJoin(    const OQueryDesignView* _pView,
      77             :                             const ::connectivity::OSQLParseNode *pNode);
      78             : 
      79             :     SqlParseError InstallFields(OQueryDesignView* _pView,
      80             :                                 const ::connectivity::OSQLParseNode* pNode,
      81             :                                 OJoinTableView::OTableWindowMap* pTabList );
      82             : 
      83             :     SqlParseError GetGroupCriteria( OQueryDesignView* _pView,
      84             :                                     OSelectionBrowseBox* _pSelectionBrw,
      85             :                                     const ::connectivity::OSQLParseNode* pSelectRoot );
      86             : 
      87             :     SqlParseError GetHavingCriteria(OQueryDesignView* _pView,
      88             :                                     OSelectionBrowseBox* _pSelectionBrw,
      89             :                                     const ::connectivity::OSQLParseNode* pSelectRoot,
      90             :                                     sal_uInt16& rLevel );
      91             : 
      92             :     SqlParseError GetOrderCriteria( OQueryDesignView* _pView,
      93             :                                     OSelectionBrowseBox* _pSelectionBrw,
      94             :                                     const ::connectivity::OSQLParseNode* pParseRoot );
      95             : 
      96             :     SqlParseError AddFunctionCondition(OQueryDesignView* _pView,
      97             :                                     OSelectionBrowseBox* _pSelectionBrw,
      98             :                                     const ::connectivity::OSQLParseNode * pCondition,
      99             :                                     const sal_uInt16 nLevel,
     100             :                                     sal_Bool bHaving,
     101             :                                     bool _bAddOrOnOneLine);
     102             : 
     103             :     //------------------------------------------------------------------------------
     104           0 :     ::rtl::OUString quoteTableAlias(sal_Bool _bQuote, const ::rtl::OUString& _sAliasName, const ::rtl::OUString& _sQuote)
     105             :     {
     106           0 :         ::rtl::OUString sRet;
     107           0 :         if ( _bQuote && !_sAliasName.isEmpty() )
     108             :         {
     109           0 :             sRet = ::dbtools::quoteName(_sQuote,_sAliasName);
     110           0 :             const static ::rtl::OUString sTableSeparater('.');
     111           0 :             sRet += sTableSeparater;
     112             :         }
     113           0 :         return sRet;
     114             :     }
     115             :     //------------------------------------------------------------------------------
     116           0 :     ::rtl::OUString getTableRange(const OQueryDesignView* _pView,const ::connectivity::OSQLParseNode* _pTableRef)
     117             :     {
     118           0 :         Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
     119           0 :         ::rtl::OUString sTableRange;
     120           0 :         if ( _pTableRef )
     121             :         {
     122           0 :             sTableRange = ::connectivity::OSQLParseNode::getTableRange(_pTableRef);
     123           0 :             if ( sTableRange.isEmpty() )
     124           0 :                 _pTableRef->parseNodeToStr(sTableRange,xConnection,NULL,sal_False,sal_False);
     125             :         }
     126           0 :         return sTableRange;
     127             :     }
     128             :     //------------------------------------------------------------------------------
     129           0 :     void insertConnection(const OQueryDesignView* _pView,const EJoinType& _eJoinType,OTableFieldDescRef _aDragLeft,OTableFieldDescRef _aDragRight,bool _bNatural = false)
     130             :     {
     131           0 :         OQueryTableView* pTableView = static_cast<OQueryTableView*>(_pView->getTableView());
     132           0 :         OQueryTableConnection* pConn = static_cast<OQueryTableConnection*>( pTableView->GetTabConn(static_cast<OTableWindow*>(_aDragLeft->GetTabWindow()),static_cast<OTableWindow*>(_aDragRight->GetTabWindow()),true));
     133             : 
     134           0 :         if ( !pConn )
     135             :         {
     136           0 :             OQueryTableConnectionData* pInfoData = new OQueryTableConnectionData();
     137           0 :             TTableConnectionData::value_type aInfoData(pInfoData);
     138           0 :             pInfoData->InitFromDrag(_aDragLeft, _aDragRight);
     139           0 :             pInfoData->SetJoinType(_eJoinType);
     140             : 
     141           0 :             if ( _bNatural )
     142             :             {
     143           0 :                 aInfoData->ResetConnLines();
     144           0 :                 pInfoData->setNatural(_bNatural);
     145             :                 try
     146             :                 {
     147           0 :                     Reference<XNameAccess> xReferencedTableColumns(aInfoData->getReferencedTable()->getColumns());
     148           0 :                     Sequence< ::rtl::OUString> aSeq = aInfoData->getReferencingTable()->getColumns()->getElementNames();
     149           0 :                     const ::rtl::OUString* pIter = aSeq.getConstArray();
     150           0 :                     const ::rtl::OUString* pEnd   = pIter + aSeq.getLength();
     151           0 :                     for(;pIter != pEnd;++pIter)
     152             :                     {
     153           0 :                         if ( xReferencedTableColumns->hasByName(*pIter) )
     154           0 :                             aInfoData->AppendConnLine(*pIter,*pIter);
     155           0 :                     }
     156             :                 }
     157           0 :                 catch( const Exception& )
     158             :                 {
     159             :                     DBG_UNHANDLED_EXCEPTION();
     160             :                 }
     161             :             }
     162             : 
     163           0 :             OQueryTableConnection aInfo(pTableView, aInfoData);
     164             :             // da ein OQueryTableConnection-Objekt nie den Besitz der uebergebenen Daten uebernimmt, sondern sich nur den Zeiger merkt,
     165             :             // ist dieser Zeiger auf eine lokale Variable hier unkritisch, denn aInfoData und aInfo haben die selbe Lebensdauer
     166           0 :             pTableView->NotifyTabConnection( aInfo );
     167             :         }
     168             :         else
     169             :         {
     170           0 :             ::rtl::OUString aSourceFieldName(_aDragLeft->GetField());
     171           0 :             ::rtl::OUString aDestFieldName(_aDragRight->GetField());
     172             :             // the connection could point on the other side
     173           0 :             if(pConn->GetSourceWin() == _aDragRight->GetTabWindow())
     174             :             {
     175           0 :                 ::rtl::OUString aTmp(aSourceFieldName);
     176           0 :                 aSourceFieldName = aDestFieldName;
     177           0 :                 aDestFieldName = aTmp;
     178             :             }
     179           0 :             pConn->GetData()->AppendConnLine( aSourceFieldName,aDestFieldName);
     180           0 :             pConn->UpdateLineList();
     181             :             // Modified-Flag
     182             :             //  SetModified();
     183             :             // und neu zeichnen
     184           0 :             pConn->RecalcLines();
     185             :                 // fuer das unten folgende Invalidate muss ich dieser neuen Connection erst mal die Moeglichkeit geben,
     186             :                 // ihr BoundingRect zu ermitteln
     187           0 :             pConn->InvalidateConnection();
     188             :         }
     189           0 :     }
     190             :     //------------------------------------------------------------------------------
     191           0 :     ::rtl::OUString ParseCondition( OQueryController& rController
     192             :                                     ,const ::connectivity::OSQLParseNode* pCondition
     193             :                                     ,const ::rtl::OUString _sDecimal
     194             :                                     ,const ::com::sun::star::lang::Locale& _rLocale
     195             :                                     ,sal_uInt32 _nStartIndex)
     196             :     {
     197           0 :         ::rtl::OUString aCondition;
     198           0 :         Reference< XConnection> xConnection = rController.getConnection();
     199           0 :         if ( xConnection.is() )
     200             :         {
     201           0 :             sal_uInt32 nCount = pCondition->count();
     202           0 :             for(sal_uInt32 i = _nStartIndex ; i < nCount ; ++i)
     203             :                 pCondition->getChild(i)->parseNodeToPredicateStr(aCondition,
     204             :                                 xConnection,
     205             :                                 rController.getNumberFormatter(),
     206             :                                 _rLocale,
     207           0 :                                 static_cast<sal_Char>(_sDecimal.toChar()),
     208           0 :                                 &rController.getParser().getContext());
     209             :         }
     210           0 :         return aCondition;
     211             :     }
     212             :     //------------------------------------------------------------------------------
     213           0 :     SqlParseError FillOuterJoins(OQueryDesignView* _pView,
     214             :                                 const ::connectivity::OSQLParseNode* pTableRefList)
     215             :     {
     216           0 :         SqlParseError eErrorCode = eOk;
     217           0 :         sal_uInt32 nCount = pTableRefList->count();
     218           0 :         sal_Bool bError = sal_False;
     219           0 :         for (sal_uInt32 i=0; !bError && i < nCount; ++i)
     220             :         {
     221           0 :             const ::connectivity::OSQLParseNode* pParseNode = pTableRefList->getChild(i);
     222           0 :             const ::connectivity::OSQLParseNode* pJoinNode = NULL;
     223             : 
     224           0 :             if ( SQL_ISRULE( pParseNode, qualified_join ) || SQL_ISRULE( pParseNode, joined_table ) || SQL_ISRULE( pParseNode, cross_union ) )
     225           0 :                 pJoinNode = pParseNode;
     226           0 :             else if(    SQL_ISRULE(pParseNode,table_ref)
     227           0 :                     &&  pParseNode->count() == 4 ) // '{' SQL_TOKEN_OJ joined_table '}'
     228           0 :                 pJoinNode = pParseNode->getChild(2);
     229             : 
     230           0 :             if ( pJoinNode )
     231             :             {
     232           0 :                 if ( !InsertJoin(_pView,pJoinNode) )
     233           0 :                     bError = sal_True;
     234             :             }
     235             :         }
     236             :         // check if error occurred
     237           0 :         if ( bError )
     238           0 :             eErrorCode = eIllegalJoin;
     239             : 
     240           0 :         return eErrorCode;
     241             :     }
     242             :     // -----------------------------------------------------------------------------
     243             : 
     244             :     /** FillDragInfo fills the field description out of the table
     245             :     */
     246             :     //------------------------------------------------------------------------------
     247           0 :     SqlParseError FillDragInfo( const OQueryDesignView* _pView,
     248             :                             const ::connectivity::OSQLParseNode* pColumnRef,
     249             :                             OTableFieldDescRef& _rDragInfo)
     250             :     {
     251           0 :         SqlParseError eErrorCode = eOk;
     252             : 
     253           0 :         sal_Bool bErg = sal_False;
     254             : 
     255           0 :         ::rtl::OUString aTableRange,aColumnName;
     256             :         sal_uInt16 nCntAccount;
     257           0 :         ::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController&>(_pView->getController()).getParseIterator();
     258           0 :         rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange );
     259             : 
     260           0 :         if ( !aTableRange.isEmpty() )
     261             :         {
     262           0 :             OQueryTableWindow*  pSTW = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( aTableRange );
     263           0 :             bErg = (pSTW && pSTW->ExistsField( aColumnName, _rDragInfo ) );
     264             :         }
     265           0 :         if ( !bErg )
     266             :         {
     267           0 :             bErg = static_cast<OQueryTableView*>(_pView->getTableView())->FindTableFromField(aColumnName, _rDragInfo, nCntAccount);
     268           0 :             if ( !bErg )
     269           0 :                 bErg = _pView->HasFieldByAliasName(aColumnName, _rDragInfo);
     270             :         }
     271           0 :         if ( !bErg )
     272             :         {
     273           0 :             eErrorCode = eColumnNotFound;
     274           0 :             String sError(ModuleRes(STR_QRY_COLUMN_NOT_FOUND));
     275           0 :             sError.SearchAndReplaceAscii("$name$",aColumnName);
     276           0 :             _pView->getController().appendError( sError );
     277             : 
     278             :             try
     279             :             {
     280           0 :                 Reference<XDatabaseMetaData> xMeta = _pView->getController().getConnection()->getMetaData();
     281           0 :                 if ( xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers() )
     282           0 :                     _pView->getController().appendError( String( ModuleRes( STR_QRY_CHECK_CASESENSITIVE ) ) );
     283             :             }
     284           0 :             catch(Exception&)
     285             :             {
     286           0 :             }
     287             :         }
     288             : 
     289           0 :         return eErrorCode;
     290             :     }
     291             :     //------------------------------------------------------------------------------
     292           0 :     ::rtl::OUString BuildJoinCriteria(  const Reference< XConnection>& _xConnection,
     293             :                                         const OConnectionLineDataVec* pLineDataList,
     294             :                                         const OQueryTableConnectionData* pData)
     295             :     {
     296           0 :         ::rtl::OUStringBuffer aCondition;
     297           0 :         if ( _xConnection.is() )
     298             :         {
     299           0 :             OConnectionLineDataVec::const_iterator aIter = pLineDataList->begin();
     300           0 :             OConnectionLineDataVec::const_iterator aEnd = pLineDataList->end();
     301             :             try
     302             :             {
     303           0 :                 const Reference< XDatabaseMetaData >  xMetaData = _xConnection->getMetaData();
     304           0 :                 const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
     305           0 :                 const ::rtl::OUString sEqual(RTL_CONSTASCII_USTRINGPARAM(" = "));
     306             : 
     307           0 :                 for(;aIter != aEnd;++aIter)
     308             :                 {
     309           0 :                     OConnectionLineDataRef pLineData = *aIter;
     310           0 :                     if(aCondition.getLength())
     311           0 :                         aCondition.append(C_AND);
     312           0 :                     aCondition.append(quoteTableAlias(sal_True,pData->GetAliasName(JTCS_FROM),aQuote));
     313           0 :                     aCondition.append(::dbtools::quoteName(aQuote, pLineData->GetFieldName(JTCS_FROM) ));
     314           0 :                     aCondition.append(sEqual);
     315           0 :                     aCondition.append(quoteTableAlias(sal_True,pData->GetAliasName(JTCS_TO),aQuote));
     316           0 :                     aCondition.append(::dbtools::quoteName(aQuote, pLineData->GetFieldName(JTCS_TO) ));
     317           0 :                 }
     318             :             }
     319           0 :             catch(SQLException&)
     320             :             {
     321             :                 OSL_FAIL("Failure while building Join criteria!");
     322             :             }
     323             :         }
     324             : 
     325           0 :         return aCondition.makeStringAndClear();
     326             :     }
     327             :     //------------------------------------------------------------------------------
     328             :     /** JoinCycle looks for a join cycle and append it to the string
     329             :         @param  _xConnection    the connection
     330             :         @param  _pEntryConn     the table connection which holds the data
     331             :         @param  _pEntryTabTo    the corresponding table window
     332             :         @param  _rJoin          the String which will contain the resulting string
     333             :     */
     334           0 :     void JoinCycle( const Reference< XConnection>& _xConnection,
     335             :                     OQueryTableConnection* _pEntryConn,
     336             :                     const OQueryTableWindow* _pEntryTabTo,
     337             :                     ::rtl::OUString& _rJoin )
     338             :     {
     339             :         OSL_ENSURE(_pEntryConn,"TableConnection can not be null!");
     340             : 
     341           0 :         OQueryTableConnectionData* pData = static_cast< OQueryTableConnectionData*>(_pEntryConn->GetData().get());
     342           0 :         if ( pData->GetJoinType() != INNER_JOIN && _pEntryTabTo->ExistsAVisitedConn() )
     343             :         {
     344           0 :             sal_Bool bBrace = sal_False;
     345           0 :             if(!_rJoin.isEmpty() && _rJoin.lastIndexOf(')') == (_rJoin.getLength()-1))
     346             :             {
     347           0 :                 bBrace = sal_True;
     348           0 :                 _rJoin = _rJoin.replaceAt(_rJoin.getLength()-1,1,::rtl::OUString(' '));
     349             :             }
     350           0 :             (_rJoin += C_AND) += BuildJoinCriteria(_xConnection,pData->GetConnLineDataList(),pData);
     351           0 :             if(bBrace)
     352           0 :                 _rJoin += ::rtl::OUString(')');
     353           0 :             _pEntryConn->SetVisited(sal_True);
     354             :         }
     355           0 :     }
     356             :     //------------------------------------------------------------------------------
     357           0 :     ::rtl::OUString BuildTable( const Reference< XConnection>& _xConnection,
     358             :                                 const OQueryTableWindow* pEntryTab,
     359             :                                 bool _bForce = false
     360             :                                 )
     361             :     {
     362           0 :         ::rtl::OUString aDBName(pEntryTab->GetComposedName());
     363             : 
     364           0 :         if( _xConnection.is() )
     365             :         {
     366             :             try
     367             :             {
     368           0 :                 Reference< XDatabaseMetaData >  xMetaData = _xConnection->getMetaData();
     369             : 
     370           0 :                 ::rtl::OUString sCatalog, sSchema, sTable;
     371           0 :                 ::dbtools::qualifiedNameComponents( xMetaData, aDBName, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
     372           0 :                 ::rtl::OUString aTableListStr = ::dbtools::composeTableNameForSelect( _xConnection, sCatalog, sSchema, sTable );
     373             : 
     374           0 :                 ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
     375           0 :                 if ( _bForce || isAppendTableAliasEnabled( _xConnection ) || pEntryTab->GetAliasName() != aDBName )
     376             :                 {
     377           0 :                     aTableListStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" "));
     378           0 :                     if ( generateAsBeforeTableAlias( _xConnection ) )
     379           0 :                         aTableListStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AS "));
     380           0 :                     aTableListStr += ::dbtools::quoteName( aQuote, pEntryTab->GetAliasName() );
     381             :                 }
     382           0 :                 aDBName = aTableListStr;
     383             :             }
     384           0 :             catch(const SQLException&)
     385             :             {
     386             :                 DBG_UNHANDLED_EXCEPTION();
     387             :             }
     388             :         }
     389           0 :         return aDBName;
     390             :     }
     391             :     //------------------------------------------------------------------------------
     392           0 :     ::rtl::OUString BuildJoin(  const Reference< XConnection>& _xConnection,
     393             :                                 const ::rtl::OUString& rLh,
     394             :                                 const ::rtl::OUString& rRh,
     395             :                                 const OQueryTableConnectionData* pData)
     396             :     {
     397             : 
     398           0 :         String aErg(rLh);
     399           0 :         if ( pData->isNatural() && pData->GetJoinType() != CROSS_JOIN )
     400           0 :             aErg.AppendAscii(" NATURAL ");
     401           0 :         switch(pData->GetJoinType())
     402             :         {
     403             :             case LEFT_JOIN:
     404           0 :                 aErg.AppendAscii(" LEFT OUTER ");
     405           0 :                 break;
     406             :             case RIGHT_JOIN:
     407           0 :                 aErg.AppendAscii(" RIGHT OUTER ");
     408           0 :                 break;
     409             :             case CROSS_JOIN:
     410             :                 OSL_ENSURE(!pData->isNatural(),"OQueryDesignView::BuildJoin: This should not happen!");
     411           0 :                 aErg.AppendAscii(" CROSS ");
     412           0 :                 break;
     413             :             case INNER_JOIN:
     414             :                 OSL_ENSURE(pData->isNatural(),"OQueryDesignView::BuildJoin: This should not happen!");
     415           0 :                 aErg.AppendAscii(" INNER ");
     416           0 :                 break;
     417             :             default:
     418           0 :                 aErg.AppendAscii(" FULL OUTER ");
     419           0 :                 break;
     420             :         }
     421           0 :         aErg.AppendAscii("JOIN ");
     422           0 :         aErg += String(rRh);
     423           0 :         if ( CROSS_JOIN != pData->GetJoinType() && !pData->isNatural() )
     424             :         {
     425           0 :             aErg.AppendAscii(" ON ");
     426           0 :             aErg += String(BuildJoinCriteria(_xConnection,pData->GetConnLineDataList(),pData));
     427             :         }
     428             : 
     429           0 :         return aErg;
     430             :     }
     431             :     //------------------------------------------------------------------------------
     432           0 :     ::rtl::OUString BuildJoin(  const Reference< XConnection>& _xConnection,
     433             :                                 const OQueryTableWindow* pLh,
     434             :                                 const OQueryTableWindow* pRh,
     435             :                                 const OQueryTableConnectionData* pData
     436             :                                 )
     437             :     {
     438           0 :         bool bForce = pData->GetJoinType() == CROSS_JOIN || pData->isNatural();
     439           0 :         return BuildJoin(_xConnection,BuildTable(_xConnection,pLh,bForce),BuildTable(_xConnection,pRh,bForce),pData);
     440             :     }
     441             :     //------------------------------------------------------------------------------
     442           0 :     ::rtl::OUString BuildJoin(  const Reference< XConnection>& _xConnection,
     443             :                                 const ::rtl::OUString &rLh,
     444             :                                 const OQueryTableWindow* pRh,
     445             :                                 const OQueryTableConnectionData* pData
     446             :                                 )
     447             :     {
     448           0 :         return BuildJoin(_xConnection,rLh,BuildTable(_xConnection,pRh),pData);
     449             :     }
     450             :     //------------------------------------------------------------------------------
     451           0 :     ::rtl::OUString BuildJoin(  const Reference< XConnection>& _xConnection,
     452             :                                 const OQueryTableWindow* pLh,
     453             :                                 const ::rtl::OUString &rRh,
     454             :                                 const OQueryTableConnectionData* pData
     455             :                                 )
     456             :     {
     457             :         // strict ANSI SQL:
     458             :         // - does not support any bracketing of JOINS
     459             :         // - supports nested joins only in the LEFT HAND SIDE
     460             :         // In this case, we are trying to build a join with a nested join
     461             :         // in the right hand side.
     462             :         // So switch the direction of the join and both hand sides.
     463           0 :         OQueryTableConnectionData data(*pData);
     464           0 :         switch (data.GetJoinType())
     465             :         {
     466             :         case LEFT_JOIN:
     467           0 :             data.SetJoinType(RIGHT_JOIN);
     468           0 :             break;
     469             :         case RIGHT_JOIN:
     470           0 :             data.SetJoinType(LEFT_JOIN);
     471           0 :             break;
     472             :         default:
     473             :             // the other join types are symmetric, so nothing to change
     474           0 :             break;
     475             :         }
     476           0 :         return BuildJoin(_xConnection, rRh, BuildTable(_xConnection,pLh), &data);
     477             :     }
     478             :     //------------------------------------------------------------------------------
     479           0 :     void GetNextJoin(   const Reference< XConnection>& _xConnection,
     480             :                         OQueryTableConnection* pEntryConn,
     481             :                         OQueryTableWindow* pEntryTabTo,
     482             :                         ::rtl::OUString &aJoin)
     483             :     {
     484           0 :         OQueryTableConnectionData* pEntryConnData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get());
     485           0 :         if ( pEntryConnData->GetJoinType() == INNER_JOIN && !pEntryConnData->isNatural() )
     486           0 :             return;
     487             : 
     488           0 :         if(aJoin.isEmpty())
     489             :         {
     490           0 :             OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin());
     491           0 :             aJoin = BuildJoin(_xConnection,pEntryTabFrom,pEntryTabTo,pEntryConnData);
     492             :         }
     493           0 :         else if(pEntryTabTo == pEntryConn->GetDestWin())
     494             :         {
     495           0 :             aJoin = BuildJoin(_xConnection,aJoin,pEntryTabTo,pEntryConnData);
     496             :         }
     497           0 :         else if(pEntryTabTo == pEntryConn->GetSourceWin())
     498             :         {
     499           0 :             aJoin = BuildJoin(_xConnection,pEntryTabTo,aJoin,pEntryConnData);
     500             :         }
     501             : 
     502           0 :         pEntryConn->SetVisited(sal_True);
     503             : 
     504             :         // first search for the "to" window
     505           0 :         const ::std::vector<OTableConnection*>* pConnections = pEntryConn->GetParent()->getTableConnections();
     506           0 :         ::std::vector<OTableConnection*>::const_iterator aIter = pConnections->begin();
     507           0 :         ::std::vector<OTableConnection*>::const_iterator aEnd = pConnections->end();
     508           0 :         for(;aIter != aEnd;++aIter)
     509             :         {
     510           0 :             OQueryTableConnection* pNext = static_cast<OQueryTableConnection*>(*aIter);
     511           0 :             if(!pNext->IsVisited() && (pNext->GetSourceWin() == pEntryTabTo || pNext->GetDestWin() == pEntryTabTo))
     512             :             {
     513           0 :                 OQueryTableWindow* pEntryTab = pNext->GetSourceWin() == pEntryTabTo ? static_cast<OQueryTableWindow*>(pNext->GetDestWin()) : static_cast<OQueryTableWindow*>(pNext->GetSourceWin());
     514             :                 // exists there a connection to a OQueryTableWindow that holds a connection that has been already visited
     515           0 :                 JoinCycle(_xConnection,pNext,pEntryTab,aJoin);
     516           0 :                 if(!pNext->IsVisited())
     517           0 :                     GetNextJoin(_xConnection,pNext,pEntryTab,aJoin);
     518             :             }
     519             :         }
     520             : 
     521             :         // when nothing found found look for the "from" window
     522           0 :         if(aIter == aEnd)
     523             :         {
     524           0 :             OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin());
     525           0 :             aIter = pConnections->begin();
     526           0 :             for(;aIter != aEnd;++aIter)
     527             :             {
     528           0 :                 OQueryTableConnection* pNext = static_cast<OQueryTableConnection*>(*aIter);
     529           0 :                 if(!pNext->IsVisited() && (pNext->GetSourceWin() == pEntryTabFrom || pNext->GetDestWin() == pEntryTabFrom))
     530             :                 {
     531           0 :                     OQueryTableWindow* pEntryTab = pNext->GetSourceWin() == pEntryTabFrom ? static_cast<OQueryTableWindow*>(pNext->GetDestWin()) : static_cast<OQueryTableWindow*>(pNext->GetSourceWin());
     532             :                     // exists there a connection to a OQueryTableWindow that holds a connection that has been already visited
     533           0 :                     JoinCycle(_xConnection,pNext,pEntryTab,aJoin);
     534           0 :                     if(!pNext->IsVisited())
     535           0 :                         GetNextJoin(_xConnection,pNext,pEntryTab,aJoin);
     536             :                 }
     537             :             }
     538             :         }
     539             :     }
     540             :     //------------------------------------------------------------------------------
     541           0 :     SqlParseError InsertJoinConnection( const OQueryDesignView* _pView,
     542             :                                     const ::connectivity::OSQLParseNode *pNode,
     543             :                                     const EJoinType& _eJoinType,
     544             :                                     const ::connectivity::OSQLParseNode *pLeftTable,
     545             :                                     const ::connectivity::OSQLParseNode *pRightTable)
     546             :     {
     547           0 :         SqlParseError eErrorCode = eOk;
     548           0 :         if (pNode->count() == 3 &&  // Ausdruck is geklammert
     549           0 :             SQL_ISPUNCTUATION(pNode->getChild(0),"(") &&
     550           0 :             SQL_ISPUNCTUATION(pNode->getChild(2),")"))
     551             :         {
     552           0 :             eErrorCode = InsertJoinConnection(_pView,pNode->getChild(1), _eJoinType,pLeftTable,pRightTable);
     553             :         }
     554           0 :         else if (SQL_ISRULEOR2(pNode,search_condition,boolean_term) &&          // AND/OR-Verknuepfung:
     555           0 :                  pNode->count() == 3)
     556             :         {
     557             :             // nur AND Verkn�pfung zulassen
     558           0 :             if (!SQL_ISTOKEN(pNode->getChild(1),AND))
     559           0 :                 eErrorCode = eIllegalJoinCondition;
     560           0 :             else if ( eOk == (eErrorCode = InsertJoinConnection(_pView,pNode->getChild(0), _eJoinType,pLeftTable,pRightTable)) )
     561           0 :                     eErrorCode = InsertJoinConnection(_pView,pNode->getChild(2), _eJoinType,pLeftTable,pRightTable);
     562             :         }
     563           0 :         else if (SQL_ISRULE(pNode,comparison_predicate))
     564             :         {
     565             :             // only the comparison of columns is allowed
     566             :             OSL_ENSURE(pNode->count() == 3,"OQueryDesignView::InsertJoinConnection: Fehler im Parse Tree");
     567           0 :             if (!(SQL_ISRULE(pNode->getChild(0),column_ref) &&
     568           0 :                   SQL_ISRULE(pNode->getChild(2),column_ref) &&
     569           0 :                    pNode->getChild(1)->getNodeType() == SQL_NODE_EQUAL))
     570             :             {
     571           0 :                 String sError(ModuleRes(STR_QRY_JOIN_COLUMN_COMPARE));
     572           0 :                 _pView->getController().appendError( sError );
     573           0 :                 return eIllegalJoin;
     574             :             }
     575             : 
     576           0 :             OTableFieldDescRef aDragLeft  = new OTableFieldDesc();
     577           0 :             OTableFieldDescRef aDragRight = new OTableFieldDesc();
     578           0 :             if ( eOk != ( eErrorCode = FillDragInfo(_pView,pNode->getChild(0),aDragLeft)) ||
     579           0 :                 eOk != ( eErrorCode = FillDragInfo(_pView,pNode->getChild(2),aDragRight)))
     580           0 :                 return eErrorCode;
     581             : 
     582           0 :             if ( pLeftTable )
     583             :             {
     584           0 :                 OQueryTableWindow*  pLeftWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pLeftTable->getByRule(OSQLParseNode::table_ref) ));
     585           0 :                 if ( pLeftWindow == aDragLeft->GetTabWindow() )
     586           0 :                     insertConnection(_pView,_eJoinType,aDragLeft,aDragRight);
     587             :                 else
     588           0 :                     insertConnection(_pView,_eJoinType,aDragRight,aDragLeft);
     589             :             }
     590             :             else
     591           0 :                 insertConnection(_pView,_eJoinType,aDragLeft,aDragRight);
     592             :         }
     593             :         else
     594           0 :             eErrorCode = eIllegalJoin;
     595           0 :         return eErrorCode;
     596             :     }
     597             :     //------------------------------------------------------------------------------
     598           0 :     sal_Bool GetInnerJoinCriteria(  const OQueryDesignView* _pView,
     599             :                                     const ::connectivity::OSQLParseNode *pCondition)
     600             :     {
     601           0 :         return InsertJoinConnection(_pView,pCondition, INNER_JOIN,NULL,NULL) != eOk;
     602             :     }
     603             :     //------------------------------------------------------------------------------
     604           0 :     ::rtl::OUString GenerateSelectList( const OQueryDesignView* _pView,
     605             :                                         OTableFields&   _rFieldList,
     606             :                                         sal_Bool bAlias)
     607             :     {
     608           0 :         Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
     609           0 :         if ( !xConnection.is() )
     610           0 :             return ::rtl::OUString();
     611             : 
     612           0 :         ::rtl::OUStringBuffer aTmpStr,aFieldListStr;
     613             : 
     614           0 :         sal_Bool bAsterix = sal_False;
     615           0 :         int nVis = 0;
     616           0 :         OTableFields::iterator aIter = _rFieldList.begin();
     617           0 :         OTableFields::iterator aEnd = _rFieldList.end();
     618           0 :         for(;aIter != aEnd;++aIter)
     619             :         {
     620           0 :             OTableFieldDescRef pEntryField = *aIter;
     621           0 :             if ( pEntryField->IsVisible() )
     622             :             {
     623           0 :                 if ( pEntryField->GetField().toChar() == '*' )
     624           0 :                     bAsterix = sal_True;
     625           0 :                 ++nVis;
     626             :             }
     627           0 :         }
     628           0 :         if(nVis == 1)
     629           0 :             bAsterix = sal_False;
     630             : 
     631             :         try
     632             :         {
     633           0 :             const Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
     634           0 :             const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
     635             : 
     636           0 :             OJoinTableView::OTableWindowMap* pTabList = _pView->getTableView()->GetTabWinMap();
     637             : 
     638           0 :             const static ::rtl::OUString sFieldSeparator(RTL_CONSTASCII_USTRINGPARAM(", "));
     639           0 :             const static ::rtl::OUString s_sAs(RTL_CONSTASCII_USTRINGPARAM(" AS "));
     640             : 
     641           0 :             aIter = _rFieldList.begin();
     642           0 :             for(;aIter != aEnd;++aIter)
     643             :             {
     644           0 :                 OTableFieldDescRef pEntryField = *aIter;
     645           0 :                 ::rtl::OUString rFieldName = pEntryField->GetField();
     646           0 :                 if ( !rFieldName.isEmpty() && pEntryField->IsVisible() )
     647             :                 {
     648           0 :                     aTmpStr = ::rtl::OUString();
     649           0 :                     const ::rtl::OUString rAlias = pEntryField->GetAlias();
     650           0 :                     const ::rtl::OUString rFieldAlias = pEntryField->GetFieldAlias();
     651             : 
     652           0 :                     aTmpStr.append(quoteTableAlias((bAlias || bAsterix),rAlias,aQuote));
     653             : 
     654             :                     // if we have a none numeric field, the table alias could be in the name
     655             :                     // otherwise we are not allowed to do this (e.g. 0.1 * PRICE )
     656           0 :                     if  ( !pEntryField->isOtherFunction() )
     657             :                     {
     658             :                         // we have to look if we have alias.* here but before we have to check if the column doesn't already exist
     659           0 :                         String sTemp = rFieldName;
     660           0 :                         OTableFieldDescRef  aInfo = new OTableFieldDesc();
     661           0 :                         OJoinTableView::OTableWindowMap::iterator tableIter = pTabList->begin();
     662           0 :                         OJoinTableView::OTableWindowMap::iterator tableEnd = pTabList->end();
     663           0 :                         sal_Bool bFound = sal_False;
     664           0 :                         for(;!bFound && tableIter != tableEnd ;++tableIter)
     665             :                         {
     666           0 :                             OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(tableIter->second);
     667             : 
     668           0 :                             bFound = pTabWin->ExistsField( rFieldName, aInfo );
     669           0 :                             if ( bFound )
     670           0 :                                 rFieldName = aInfo->GetField();
     671             :                         }
     672           0 :                         if ( ( rFieldName.toChar() != '*' ) && ( rFieldName.indexOf( aQuote ) == -1 ) )
     673             :                         {
     674             :                             OSL_ENSURE(!pEntryField->GetTable().isEmpty(),"No table field name!");
     675           0 :                             aTmpStr.append(::dbtools::quoteName(aQuote, rFieldName));
     676             :                         }
     677             :                         else
     678           0 :                             aTmpStr.append(rFieldName);
     679             :                     }
     680             :                     else
     681           0 :                         aTmpStr.append(rFieldName);
     682             : 
     683           0 :                     if  ( pEntryField->isAggreateFunction() )
     684             :                     {
     685             :                         OSL_ENSURE(!pEntryField->GetFunction().isEmpty(),"Functionname darf hier nicht leer sein! ;-(");
     686           0 :                         ::rtl::OUStringBuffer aTmpStr2( pEntryField->GetFunction());
     687           0 :                         aTmpStr2.appendAscii("(");
     688           0 :                         aTmpStr2.append(aTmpStr.makeStringAndClear());
     689           0 :                         aTmpStr2.appendAscii(")");
     690           0 :                         aTmpStr = aTmpStr2;
     691             :                     }
     692             : 
     693           0 :                     if (!rFieldAlias.isEmpty()                         &&
     694           0 :                         (rFieldName.toChar() != '*'                     ||
     695           0 :                         pEntryField->isNumericOrAggreateFunction()      ||
     696           0 :                         pEntryField->isOtherFunction()))
     697             :                     {
     698           0 :                         aTmpStr.append(s_sAs);
     699           0 :                         aTmpStr.append(::dbtools::quoteName(aQuote, rFieldAlias));
     700             :                     }
     701           0 :                     aFieldListStr.append(aTmpStr.makeStringAndClear());
     702           0 :                     aFieldListStr.append(sFieldSeparator);
     703             :                 }
     704           0 :             }
     705           0 :             if(aFieldListStr.getLength())
     706           0 :                 aFieldListStr.setLength(aFieldListStr.getLength()-2);
     707             :         }
     708           0 :         catch(SQLException&)
     709             :         {
     710             :             OSL_FAIL("Failure while building select list!");
     711             :         }
     712           0 :         return aFieldListStr.makeStringAndClear();
     713             :     }
     714             :     //------------------------------------------------------------------------------
     715           0 :     sal_Bool GenerateCriterias( OQueryDesignView* _pView,
     716             :                                 ::rtl::OUStringBuffer& rRetStr,
     717             :                                 ::rtl::OUStringBuffer& rHavingStr,
     718             :                                 OTableFields& _rFieldList,
     719             :                                 sal_Bool bMulti )
     720             :     {
     721             :         // * darf keine Filter enthalten : habe ich die entsprechende Warnung schon angezeigt ?
     722           0 :         sal_Bool bCritsOnAsterikWarning = sal_False;        // ** TMFS **
     723             : 
     724           0 :         ::rtl::OUString aFieldName,aCriteria,aWhereStr,aHavingStr,aWork/*,aOrderStr*/;
     725             :         // Zeilenweise werden die Ausdr"ucke mit AND verknuepft
     726           0 :         sal_uInt16 nMaxCriteria = 0;
     727           0 :         OTableFields::iterator aIter = _rFieldList.begin();
     728           0 :         OTableFields::iterator aEnd = _rFieldList.end();
     729           0 :         for(;aIter != aEnd;++aIter)
     730             :         {
     731           0 :             nMaxCriteria = ::std::max<sal_uInt16>(nMaxCriteria,(sal_uInt16)(*aIter)->GetCriteria().size());
     732             :         }
     733           0 :         Reference< XConnection> xConnection = static_cast<OQueryController&>(_pView->getController()).getConnection();
     734           0 :         if(!xConnection.is())
     735           0 :             return sal_False;
     736             :         try
     737             :         {
     738           0 :             const Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
     739           0 :             const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
     740           0 :             const IParseContext& rContext = static_cast<OQueryController&>(_pView->getController()).getParser().getContext();
     741             : 
     742           0 :             for (sal_uInt16 i=0 ; i < nMaxCriteria ; i++)
     743             :             {
     744           0 :                 aHavingStr = aWhereStr = ::rtl::OUString();
     745             : 
     746           0 :                 for(aIter = _rFieldList.begin();aIter != aEnd;++aIter)
     747             :                 {
     748           0 :                     OTableFieldDescRef  pEntryField = *aIter;
     749           0 :                     aFieldName = pEntryField->GetField();
     750             : 
     751           0 :                     if (aFieldName.isEmpty())
     752           0 :                         continue;
     753           0 :                     aCriteria = pEntryField->GetCriteria( i );
     754           0 :                     if ( !aCriteria.isEmpty() )
     755             :                     {
     756             :                         // * is not allowed to contain any filter, only when used in combination an aggregate function
     757           0 :                         if ( aFieldName.toChar() == '*' && pEntryField->isNoneFunction() )
     758             :                         {
     759             :                             // only show the messagebox the first time
     760           0 :                             if (!bCritsOnAsterikWarning)
     761           0 :                                 ErrorBox(_pView, ModuleRes( ERR_QRY_CRITERIA_ON_ASTERISK)).Execute();
     762           0 :                             bCritsOnAsterikWarning = sal_True;
     763           0 :                             continue;
     764             :                         }
     765           0 :                         aWork = ::rtl::OUString();
     766             : 
     767             : 
     768           0 :                         aWork += quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
     769             : 
     770           0 :                         if ( (pEntryField->GetFunctionType() & (FKT_OTHER|FKT_NUMERIC)) || (aFieldName.toChar() == '*') )
     771           0 :                             aWork += aFieldName;
     772             :                         else
     773           0 :                             aWork += ::dbtools::quoteName(aQuote, aFieldName);
     774             : 
     775           0 :                         if ( pEntryField->isAggreateFunction() || pEntryField->IsGroupBy() )
     776             :                         {
     777           0 :                             if (aHavingStr.isEmpty())            // noch keine Kriterien
     778           0 :                                 aHavingStr += ::rtl::OUString('(');         // Klammern
     779             :                             else
     780           0 :                                 aHavingStr += C_AND;
     781             : 
     782           0 :                             if ( pEntryField->isAggreateFunction() )
     783             :                             {
     784             :                                 OSL_ENSURE(!pEntryField->GetFunction().isEmpty(),"No function name for aggregate given!");
     785           0 :                                 aHavingStr += pEntryField->GetFunction();
     786           0 :                                 aHavingStr += ::rtl::OUString('(');         // Klammern
     787           0 :                                 aHavingStr += aWork;
     788           0 :                                 aHavingStr += ::rtl::OUString(')');         // Klammern
     789             :                             }
     790             :                             else
     791           0 :                                 aHavingStr += aWork;
     792             : 
     793           0 :                             ::rtl::OUString aTmp = aCriteria;
     794           0 :                             ::rtl::OUString aErrorMsg;
     795           0 :                             Reference<XPropertySet> xColumn;
     796             :                             SAL_WNODEPRECATED_DECLARATIONS_PUSH
     797           0 :                             ::std::auto_ptr< ::connectivity::OSQLParseNode> pParseNode(_pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn));
     798             :                             SAL_WNODEPRECATED_DECLARATIONS_POP
     799           0 :                             if (pParseNode.get())
     800             :                             {
     801           0 :                                 if (bMulti && !(pEntryField->isOtherFunction() || (aFieldName.toChar() == '*')))
     802           0 :                                     pParseNode->replaceNodeValue(pEntryField->GetAlias(),aFieldName);
     803           0 :                                 ::rtl::OUString sHavingStr = aHavingStr;
     804             : 
     805           0 :                                 sal_uInt32 nCount = pParseNode->count();
     806           0 :                                 for( sal_uInt32 node = 1 ; node < nCount ; ++node)
     807             :                                     pParseNode->getChild(node)->parseNodeToStr( sHavingStr,
     808             :                                                                 xConnection,
     809             :                                                                 &rContext,
     810             :                                                                 sal_False,
     811           0 :                                                                 !pEntryField->isOtherFunction());
     812           0 :                                 aHavingStr = sHavingStr;
     813             :                             }
     814             :                             else
     815           0 :                                 aHavingStr += aCriteria;
     816             :                         }
     817             :                         else
     818             :                         {
     819           0 :                             if ( aWhereStr.isEmpty() )           // noch keine Kriterien
     820           0 :                                 aWhereStr += ::rtl::OUString('(');          // Klammern
     821             :                             else
     822           0 :                                 aWhereStr += C_AND;
     823             : 
     824           0 :                             aWhereStr += ::rtl::OUString(' ');
     825             :                             // aCriteria could have some german numbers so I have to be sure here
     826           0 :                             ::rtl::OUString aTmp = aCriteria;
     827           0 :                             ::rtl::OUString aErrorMsg;
     828           0 :                             Reference<XPropertySet> xColumn;
     829             :                             SAL_WNODEPRECATED_DECLARATIONS_PUSH
     830           0 :                             ::std::auto_ptr< ::connectivity::OSQLParseNode> pParseNode( _pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn));
     831             :                             SAL_WNODEPRECATED_DECLARATIONS_POP
     832           0 :                             if (pParseNode.get())
     833             :                             {
     834           0 :                                 if (bMulti && !(pEntryField->isOtherFunction() || (aFieldName.toChar() == '*')))
     835           0 :                                     pParseNode->replaceNodeValue(pEntryField->GetAlias(),aFieldName);
     836           0 :                                 ::rtl::OUString aWhere = aWhereStr;
     837             :                                 pParseNode->parseNodeToStr( aWhere,
     838             :                                                             xConnection,
     839             :                                                             &rContext,
     840             :                                                             sal_False,
     841           0 :                                                             !pEntryField->isOtherFunction() );
     842           0 :                                 aWhereStr = aWhere;
     843             :                             }
     844             :                             else
     845             :                             {
     846           0 :                                 aWhereStr += aWork;
     847           0 :                                 aWhereStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("="));
     848           0 :                                 aWhereStr += aCriteria;
     849           0 :                             }
     850             :                         }
     851             :                     }
     852             :                     // nur einmal f�r jedes Feld
     853           0 :                     else if ( !i && pEntryField->isCondition() )
     854             :                     {
     855           0 :                         if (aWhereStr.isEmpty())         // noch keine Kriterien
     856           0 :                             aWhereStr += ::rtl::OUString('(');          // Klammern
     857             :                         else
     858           0 :                             aWhereStr += C_AND;
     859           0 :                         aWhereStr += pEntryField->GetField();
     860             :                     }
     861           0 :                 }
     862           0 :                 if (!aWhereStr.isEmpty())
     863             :                 {
     864           0 :                     aWhereStr += ::rtl::OUString(')');                      // Klammern zu fuer 'AND' Zweig
     865           0 :                     if (rRetStr.getLength())                            // schon Feldbedingungen ?
     866           0 :                         rRetStr.append(C_OR);
     867             :                     else                                        // Klammern auf fuer 'OR' Zweig
     868           0 :                         rRetStr.append(sal_Unicode('('));
     869           0 :                     rRetStr.append(aWhereStr);
     870             :                 }
     871           0 :                 if (!aHavingStr.isEmpty())
     872             :                 {
     873           0 :                     aHavingStr += ::rtl::OUString(')');                     // Klammern zu fuer 'AND' Zweig
     874           0 :                     if (rHavingStr.getLength())                         // schon Feldbedingungen ?
     875           0 :                         rHavingStr.append(C_OR);
     876             :                     else                                        // Klammern auf fuer 'OR' Zweig
     877           0 :                         rHavingStr.append(sal_Unicode('('));
     878           0 :                     rHavingStr.append(aHavingStr);
     879             :                 }
     880             :             }
     881             : 
     882           0 :             if (rRetStr.getLength())
     883           0 :                 rRetStr.append(sal_Unicode(')'));                               // Klammern zu fuer 'OR' Zweig
     884           0 :             if (rHavingStr.getLength())
     885           0 :                 rHavingStr.append(sal_Unicode(')'));                                // Klammern zu fuer 'OR' Zweig
     886             :         }
     887           0 :         catch(SQLException&)
     888             :         {
     889             :             OSL_FAIL("Failure while building where clause!");
     890             :         }
     891           0 :         return sal_True;
     892             :     }
     893             :     //------------------------------------------------------------------------------
     894           0 :     SqlParseError GenerateOrder(    OQueryDesignView* _pView,
     895             :                                     OTableFields& _rFieldList,
     896             :                                     sal_Bool bMulti,
     897             :                                     ::rtl::OUString& _rsRet)
     898             :     {
     899           0 :         const OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
     900           0 :         Reference< XConnection> xConnection = rController.getConnection();
     901           0 :         if ( !xConnection.is() )
     902           0 :             return eNoConnection;
     903             : 
     904           0 :         SqlParseError eErrorCode = eOk;
     905             : 
     906           0 :         ::rtl::OUString aColumnName;
     907           0 :         ::rtl::OUString aWorkStr;
     908             :         try
     909             :         {
     910           0 :             const bool bColumnAliasInOrderBy = rController.getSdbMetaData().supportsColumnAliasInOrderBy();
     911           0 :             Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
     912           0 :             ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
     913             :             // * darf keine Filter enthalten : habe ich die entsprechende Warnung schon angezeigt ?
     914           0 :             sal_Bool bCritsOnAsterikWarning = sal_False;        // ** TMFS **
     915           0 :             OTableFields::iterator aIter = _rFieldList.begin();
     916           0 :             OTableFields::iterator aEnd = _rFieldList.end();
     917           0 :             for(;aIter != aEnd;++aIter)
     918             :             {
     919           0 :                 OTableFieldDescRef  pEntryField = *aIter;
     920           0 :                 EOrderDir eOrder = pEntryField->GetOrderDir();
     921             : 
     922             :                 // nur wenn eine Sortierung und ein Tabellenname vorhanden ist-> erzeugen
     923             :                 // sonst werden die Expressions vom Order By im GenerateCriteria mit erzeugt
     924           0 :                 if ( eOrder != ORDER_NONE )
     925             :                 {
     926           0 :                     aColumnName = pEntryField->GetField();
     927           0 :                     if(aColumnName.toChar() == '*')
     928             :                     {
     929             :                         // die entsprechende MessageBox nur beim ersten mal anzeigen
     930           0 :                         if (!bCritsOnAsterikWarning)
     931           0 :                             ErrorBox(_pView, ModuleRes( ERR_QRY_ORDERBY_ON_ASTERISK)).Execute();
     932           0 :                         bCritsOnAsterikWarning = sal_True;
     933           0 :                         continue;
     934             :                     }
     935             : 
     936           0 :                     if ( bColumnAliasInOrderBy && !pEntryField->GetFieldAlias().isEmpty() )
     937             :                     {
     938           0 :                         aWorkStr += ::dbtools::quoteName(aQuote, pEntryField->GetFieldAlias());
     939             :                     }
     940           0 :                     else if ( pEntryField->isNumericOrAggreateFunction() )
     941             :                     {
     942             :                         OSL_ENSURE(!pEntryField->GetFunction().isEmpty(),"Functionname darf hier nicht leer sein! ;-(");
     943           0 :                         aWorkStr += pEntryField->GetFunction();
     944           0 :                         aWorkStr +=  ::rtl::OUString('(');
     945           0 :                         aWorkStr += quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
     946             :                         // only quote column name when we don't have a numeric
     947           0 :                         if ( pEntryField->isNumeric() )
     948           0 :                             aWorkStr += aColumnName;
     949             :                         else
     950           0 :                             aWorkStr += ::dbtools::quoteName(aQuote, aColumnName);
     951             : 
     952           0 :                         aWorkStr +=  ::rtl::OUString(')');
     953             :                     }
     954           0 :                     else if ( pEntryField->isOtherFunction() )
     955             :                     {
     956           0 :                         aWorkStr += aColumnName;
     957             :                     }
     958             :                     else
     959             :                     {
     960           0 :                         aWorkStr += quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
     961           0 :                         aWorkStr += ::dbtools::quoteName(aQuote, aColumnName);
     962             :                     }
     963           0 :                     aWorkStr += rtl::OUString(' ');
     964           0 :                     aWorkStr += rtl::OUString( ";ASC;DESC" ).getToken( (sal_uInt16)eOrder, ';' );
     965           0 :                     aWorkStr += rtl::OUString(',');
     966             :                 }
     967           0 :             }
     968             : 
     969             :             {
     970           0 :                 String sTemp(comphelper::string::stripEnd(aWorkStr, ','));
     971           0 :                 aWorkStr = sTemp;
     972             :             }
     973             : 
     974           0 :             if ( !aWorkStr.isEmpty() )
     975             :             {
     976           0 :                 const sal_Int32 nMaxOrder = xMetaData->getMaxColumnsInOrderBy();
     977           0 :                 String sToken(aWorkStr);
     978           0 :                 if ( nMaxOrder && nMaxOrder < comphelper::string::getTokenCount(sToken, ',') )
     979           0 :                     eErrorCode = eStatementTooLong;
     980             :                 else
     981             :                 {
     982           0 :                     _rsRet = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ORDER BY "));
     983           0 :                     _rsRet += aWorkStr;
     984           0 :                 }
     985           0 :             }
     986             :         }
     987           0 :         catch(SQLException&)
     988             :         {
     989             :             OSL_FAIL("Failure while building group by!");
     990             :         }
     991             : 
     992           0 :         return eErrorCode;
     993             :     }
     994             : 
     995             :     //------------------------------------------------------------------------------
     996           0 :     void GenerateInnerJoinCriterias(const Reference< XConnection>& _xConnection,
     997             :                                     ::rtl::OUString& _rJoinCrit,
     998             :                                     const ::std::vector<OTableConnection*>* _pConnList)
     999             :     {
    1000           0 :         ::std::vector<OTableConnection*>::const_iterator aIter = _pConnList->begin();
    1001           0 :         ::std::vector<OTableConnection*>::const_iterator aEnd = _pConnList->end();
    1002           0 :         for(;aIter != aEnd;++aIter)
    1003             :         {
    1004           0 :             const OQueryTableConnection* pEntryConn = static_cast<const OQueryTableConnection*>(*aIter);
    1005           0 :             OQueryTableConnectionData* pEntryConnData = static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get());
    1006           0 :             if ( pEntryConnData->GetJoinType() == INNER_JOIN && !pEntryConnData->isNatural() )
    1007             :             {
    1008           0 :                 if(!_rJoinCrit.isEmpty())
    1009           0 :                     _rJoinCrit += C_AND;
    1010           0 :                 _rJoinCrit += BuildJoinCriteria(_xConnection,pEntryConnData->GetConnLineDataList(),pEntryConnData);
    1011             :             }
    1012             :         }
    1013           0 :     }
    1014             :     //------------------------------------------------------------------------------
    1015           0 :     void searchAndAppendName(const Reference< XConnection>& _xConnection,
    1016             :                              const OQueryTableWindow* _pTableWindow,
    1017             :                              ::std::map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess>& _rTableNames,
    1018             :                              ::rtl::OUString& _rsTableListStr
    1019             :                              )
    1020             :     {
    1021           0 :         ::rtl::OUString sTabName(BuildTable(_xConnection,_pTableWindow));
    1022             : 
    1023           0 :         if(_rTableNames.find(sTabName) == _rTableNames.end())
    1024             :         {
    1025           0 :             _rTableNames[sTabName] = sal_True;
    1026           0 :             _rsTableListStr += sTabName;
    1027           0 :             _rsTableListStr += ::rtl::OUString(',');
    1028           0 :         }
    1029           0 :     }
    1030             :     //------------------------------------------------------------------------------
    1031           0 :     ::rtl::OUString GenerateFromClause( const Reference< XConnection>& _xConnection,
    1032             :                                         const OQueryTableView::OTableWindowMap* pTabList,
    1033             :                                         const ::std::vector<OTableConnection*>* pConnList
    1034             :                                         )
    1035             :     {
    1036             : 
    1037           0 :         ::rtl::OUString aTableListStr;
    1038             :         // wird gebraucht um sicher zustelllen das eine Tabelle nicht doppelt vorkommt
    1039           0 :         ::std::map< ::rtl::OUString,sal_Bool,::comphelper::UStringMixLess> aTableNames;
    1040             : 
    1041             :         // generate outer join clause in from
    1042           0 :         if(!pConnList->empty())
    1043             :         {
    1044           0 :             ::std::vector<OTableConnection*>::const_iterator aIter = pConnList->begin();
    1045           0 :             ::std::vector<OTableConnection*>::const_iterator aEnd = pConnList->end();
    1046           0 :             ::std::map<OTableWindow*,sal_Int32> aConnectionCount;
    1047           0 :             for(;aIter != aEnd;++aIter)
    1048             :             {
    1049           0 :                 static_cast<OQueryTableConnection*>(*aIter)->SetVisited(sal_False);
    1050           0 :                 ++aConnectionCount[(*aIter)->GetSourceWin()];
    1051           0 :                 ++aConnectionCount[(*aIter)->GetDestWin()];
    1052             :             }
    1053           0 :             ::std::multimap<sal_Int32 , OTableWindow*> aMulti;
    1054           0 :             ::std::map<OTableWindow*,sal_Int32>::iterator aCountIter = aConnectionCount.begin();
    1055           0 :             ::std::map<OTableWindow*,sal_Int32>::iterator aCountEnd = aConnectionCount.end();
    1056           0 :             for(;aCountIter != aCountEnd;++aCountIter)
    1057             :             {
    1058           0 :                 aMulti.insert(::std::multimap<sal_Int32 , OTableWindow*>::value_type(aCountIter->second,aCountIter->first));
    1059             :             }
    1060             : 
    1061           0 :             const sal_Bool bUseEscape = ::dbtools::getBooleanDataSourceSetting( _xConnection, PROPERTY_OUTERJOINESCAPE.ascii );
    1062           0 :             ::std::multimap<sal_Int32 , OTableWindow*>::reverse_iterator aRIter = aMulti.rbegin();
    1063           0 :             ::std::multimap<sal_Int32 , OTableWindow*>::reverse_iterator aREnd = aMulti.rend();
    1064           0 :             for(;aRIter != aREnd;++aRIter)
    1065             :             {
    1066           0 :                 ::std::vector<OTableConnection*>::const_iterator aConIter = aRIter->second->getTableView()->getTableConnections(aRIter->second);
    1067           0 :                 for(;aConIter != aEnd;++aConIter)
    1068             :                 {
    1069           0 :                     OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aConIter);
    1070           0 :                     if(!pEntryConn->IsVisited() && pEntryConn->GetSourceWin() == aRIter->second )
    1071             :                     {
    1072           0 :                         ::rtl::OUString aJoin;
    1073           0 :                         GetNextJoin(_xConnection,pEntryConn,static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),aJoin);
    1074             : 
    1075           0 :                         if(!aJoin.isEmpty())
    1076             :                         {
    1077             :                             // insert tables into table list to avoid double entries
    1078           0 :                             OQueryTableWindow* pEntryTabFrom = static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin());
    1079           0 :                             OQueryTableWindow* pEntryTabTo = static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin());
    1080             : 
    1081           0 :                             ::rtl::OUString sTabName(BuildTable(_xConnection,pEntryTabFrom));
    1082           0 :                             if(aTableNames.find(sTabName) == aTableNames.end())
    1083           0 :                                 aTableNames[sTabName] = sal_True;
    1084           0 :                             sTabName = BuildTable(_xConnection,pEntryTabTo);
    1085           0 :                             if(aTableNames.find(sTabName) == aTableNames.end())
    1086           0 :                                 aTableNames[sTabName] = sal_True;
    1087             : 
    1088           0 :                             ::rtl::OUString aStr;
    1089           0 :                             switch(static_cast<OQueryTableConnectionData*>(pEntryConn->GetData().get())->GetJoinType())
    1090             :                             {
    1091             :                                 case LEFT_JOIN:
    1092             :                                 case RIGHT_JOIN:
    1093             :                                 case FULL_JOIN:
    1094             :                                     {
    1095             :                                         // create outer join
    1096           0 :                                         if ( bUseEscape )
    1097           0 :                                             aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("{ OJ "));
    1098           0 :                                         aStr += aJoin;
    1099           0 :                                         if ( bUseEscape )
    1100           0 :                                             aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" }"));
    1101             :                                     }
    1102           0 :                                     break;
    1103             :                                 default:
    1104           0 :                                     aStr += aJoin;
    1105           0 :                                     break;
    1106             :                             }
    1107           0 :                             aStr += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
    1108           0 :                             aTableListStr += aStr;
    1109           0 :                         }
    1110             :                     }
    1111             :                 }
    1112             :             }
    1113             : 
    1114             :             // and now all inner joins
    1115             :             // these are implemented as
    1116             :             // "FROM tbl1, tbl2 WHERE tbl1.col1=tlb2.col2"
    1117             :             // rather than
    1118             :             // "FROM tbl1 INNER JOIN tbl2 ON tbl1.col1=tlb2.col2"
    1119           0 :             aIter = pConnList->begin();
    1120           0 :             for(;aIter != aEnd;++aIter)
    1121             :             {
    1122           0 :                 OQueryTableConnection* pEntryConn = static_cast<OQueryTableConnection*>(*aIter);
    1123           0 :                 if(!pEntryConn->IsVisited())
    1124             :                 {
    1125             :                     searchAndAppendName(_xConnection,
    1126           0 :                                         static_cast<OQueryTableWindow*>(pEntryConn->GetSourceWin()),
    1127             :                                         aTableNames,
    1128           0 :                                         aTableListStr);
    1129             : 
    1130             :                     searchAndAppendName(_xConnection,
    1131           0 :                                         static_cast<OQueryTableWindow*>(pEntryConn->GetDestWin()),
    1132             :                                         aTableNames,
    1133           0 :                                         aTableListStr);
    1134             :                 }
    1135           0 :             }
    1136             :         }
    1137             :         // all tables that haven't a connection to anyone
    1138           0 :         OQueryTableView::OTableWindowMap::const_iterator aTabIter = pTabList->begin();
    1139           0 :         OQueryTableView::OTableWindowMap::const_iterator aTabEnd = pTabList->end();
    1140           0 :         for(;aTabIter != aTabEnd;++aTabIter)
    1141             :         {
    1142           0 :             const OQueryTableWindow* pEntryTab = static_cast<const OQueryTableWindow*>(aTabIter->second);
    1143           0 :             if(!pEntryTab->ExistsAConn())
    1144             :             {
    1145           0 :                 aTableListStr += BuildTable(_xConnection,pEntryTab);
    1146           0 :                 aTableListStr += ::rtl::OUString(',');
    1147             :             }
    1148             :         }
    1149             : 
    1150           0 :         if(!aTableListStr.isEmpty())
    1151           0 :             aTableListStr = aTableListStr.replaceAt(aTableListStr.getLength()-1,1, ::rtl::OUString() );
    1152           0 :         return aTableListStr;
    1153             :     }
    1154             :     //------------------------------------------------------------------------------
    1155           0 :     ::rtl::OUString GenerateGroupBy(const OQueryDesignView* _pView,OTableFields& _rFieldList, sal_Bool bMulti )
    1156             :     {
    1157           0 :         OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
    1158           0 :         const Reference< XConnection> xConnection = rController.getConnection();
    1159           0 :         if(!xConnection.is())
    1160           0 :             return ::rtl::OUString();
    1161             : 
    1162           0 :         ::std::map< rtl::OUString,bool> aGroupByNames;
    1163             : 
    1164           0 :         ::rtl::OUString aGroupByStr;
    1165             :         try
    1166             :         {
    1167           0 :             const Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
    1168           0 :             const ::rtl::OUString aQuote = xMetaData->getIdentifierQuoteString();
    1169             : 
    1170           0 :             OTableFields::iterator aIter = _rFieldList.begin();
    1171           0 :             OTableFields::iterator aEnd = _rFieldList.end();
    1172           0 :             for(;aIter != aEnd;++aIter)
    1173             :             {
    1174           0 :                 OTableFieldDescRef  pEntryField = *aIter;
    1175           0 :                 if ( pEntryField->IsGroupBy() )
    1176             :                 {
    1177             :                     OSL_ENSURE(!pEntryField->GetField().isEmpty(),"Kein FieldName vorhanden!;-(");
    1178           0 :                     ::rtl::OUString sGroupByPart = quoteTableAlias(bMulti,pEntryField->GetAlias(),aQuote);
    1179             : 
    1180             :                     // only quote the field name when it isn't calculated
    1181           0 :                     if ( pEntryField->isNoneFunction() )
    1182             :                     {
    1183           0 :                         sGroupByPart += ::dbtools::quoteName(aQuote, pEntryField->GetField());
    1184             :                     }
    1185             :                     else
    1186             :                     {
    1187           0 :                         ::rtl::OUString aTmp = pEntryField->GetField();
    1188           0 :                         ::rtl::OUString aErrorMsg;
    1189           0 :                         Reference<XPropertySet> xColumn;
    1190             :                         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1191           0 :                         ::std::auto_ptr< ::connectivity::OSQLParseNode> pParseNode(_pView->getPredicateTreeFromEntry(pEntryField,aTmp,aErrorMsg,xColumn));
    1192             :                         SAL_WNODEPRECATED_DECLARATIONS_POP
    1193           0 :                         if (pParseNode.get())
    1194             :                         {
    1195           0 :                             ::rtl::OUString sGroupBy;
    1196             :                             pParseNode->getChild(0)->parseNodeToStr(    sGroupBy,
    1197             :                                                         xConnection,
    1198           0 :                                                         &rController.getParser().getContext(),
    1199             :                                                         sal_False,
    1200           0 :                                                         !pEntryField->isOtherFunction());
    1201           0 :                             sGroupByPart += sGroupBy;
    1202             :                         }
    1203             :                         else
    1204           0 :                             sGroupByPart += pEntryField->GetField();
    1205             :                     }
    1206           0 :                     if ( aGroupByNames.find(sGroupByPart) == aGroupByNames.end() )
    1207             :                     {
    1208           0 :                         aGroupByNames.insert(::std::map< rtl::OUString,bool>::value_type(sGroupByPart,true));
    1209           0 :                         aGroupByStr += sGroupByPart;
    1210           0 :                         aGroupByStr += ::rtl::OUString(',');
    1211           0 :                     }
    1212             :                 }
    1213           0 :             }
    1214           0 :             if ( !aGroupByStr.isEmpty() )
    1215             :             {
    1216           0 :                 aGroupByStr = aGroupByStr.replaceAt(aGroupByStr.getLength()-1,1, ::rtl::OUString(' ') );
    1217           0 :                 ::rtl::OUString aGroupByStr2(RTL_CONSTASCII_USTRINGPARAM(" GROUP BY "));
    1218           0 :                 aGroupByStr2 += aGroupByStr;
    1219           0 :                 aGroupByStr = aGroupByStr2;
    1220           0 :             }
    1221             :         }
    1222           0 :         catch(SQLException&)
    1223             :         {
    1224             :             OSL_FAIL("Failure while building group by!");
    1225             :         }
    1226           0 :         return aGroupByStr;
    1227             :     }
    1228             :     // -----------------------------------------------------------------------------
    1229             :     SqlParseError GetORCriteria(OQueryDesignView* _pView,
    1230             :                                 OSelectionBrowseBox* _pSelectionBrw,
    1231             :                                 const ::connectivity::OSQLParseNode * pCondition,
    1232             :                                 sal_uInt16& nLevel ,
    1233             :                                 sal_Bool bHaving = sal_False,
    1234             :                                 bool bAddOrOnOneLine = false);
    1235             :     // -----------------------------------------------------------------------------
    1236           0 :     SqlParseError GetSelectionCriteria( OQueryDesignView* _pView,
    1237             :                                         OSelectionBrowseBox* _pSelectionBrw,
    1238             :                                         const ::connectivity::OSQLParseNode* pNode,
    1239             :                                         sal_uInt16& rLevel )
    1240             :     {
    1241           0 :         if (!SQL_ISRULE(pNode, select_statement))
    1242           0 :             return eNoSelectStatement;
    1243             : 
    1244             :         // nyi: mehr Pruefung auf korrekte Struktur!
    1245           0 :         pNode = pNode ? pNode->getChild(3)->getChild(1) : NULL;
    1246             :         // no where clause found
    1247           0 :         if (!pNode || pNode->isLeaf())
    1248           0 :             return eOk;
    1249             : 
    1250             :         // Naechster freier Satz ...
    1251           0 :         SqlParseError eErrorCode = eOk;
    1252           0 :         ::connectivity::OSQLParseNode * pCondition = pNode->getChild(1);
    1253           0 :         if ( pCondition ) // no where clause
    1254             :         {
    1255             :             // now we have to chech the other conditions
    1256             :             // first make the logical easier
    1257           0 :             ::connectivity::OSQLParseNode::negateSearchCondition(pCondition);
    1258           0 :             ::connectivity::OSQLParseNode *pNodeTmp = pNode->getChild(1);
    1259             : 
    1260           0 :             ::connectivity::OSQLParseNode::disjunctiveNormalForm(pNodeTmp);
    1261           0 :             pNodeTmp = pNode->getChild(1);
    1262           0 :             ::connectivity::OSQLParseNode::absorptions(pNodeTmp);
    1263           0 :             pNodeTmp = pNode->getChild(1);
    1264             :             // compress sort the criteria @see http://www.openoffice.org/issues/show_bug.cgi?id=24079
    1265           0 :             OSQLParseNode::compress(pNodeTmp);
    1266           0 :             pNodeTmp = pNode->getChild(1);
    1267             : 
    1268             :             // first extract the inner joins conditions
    1269           0 :             GetInnerJoinCriteria(_pView,pNodeTmp);
    1270             :             // now simplify again, join are checked in ComparisonPredicate
    1271           0 :             ::connectivity::OSQLParseNode::absorptions(pNodeTmp);
    1272           0 :             pNodeTmp = pNode->getChild(1);
    1273             : 
    1274             :             // it could happen that pCondition is not more valid
    1275           0 :             eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pNodeTmp, rLevel);
    1276             :         }
    1277           0 :         return eErrorCode;
    1278             :     }
    1279             :     //------------------------------------------------------------------------------
    1280             :     SqlParseError GetANDCriteria(   OQueryDesignView* _pView,
    1281             :                                     OSelectionBrowseBox* _pSelectionBrw,
    1282             :                                     const  ::connectivity::OSQLParseNode * pCondition,
    1283             :                                     sal_uInt16& nLevel,
    1284             :                                     sal_Bool bHaving,
    1285             :                                     bool bAddOrOnOneLine);
    1286             :     //------------------------------------------------------------------------------
    1287             :     SqlParseError ComparisonPredicate(OQueryDesignView* _pView,
    1288             :                             OSelectionBrowseBox* _pSelectionBrw,
    1289             :                             const ::connectivity::OSQLParseNode * pCondition,
    1290             :                             const sal_uInt16 nLevel,
    1291             :                             sal_Bool bHaving,
    1292             :                             bool bAddOrOnOneLine);
    1293             :     //------------------------------------------------------------------------------
    1294           0 :     SqlParseError GetORCriteria(OQueryDesignView* _pView,
    1295             :                                 OSelectionBrowseBox* _pSelectionBrw,
    1296             :                                 const ::connectivity::OSQLParseNode * pCondition,
    1297             :                                 sal_uInt16& nLevel ,
    1298             :                                 sal_Bool bHaving,
    1299             :                                 bool bAddOrOnOneLine)
    1300             :     {
    1301           0 :         SqlParseError eErrorCode = eOk;
    1302             : 
    1303             :         // Runde Klammern um den Ausdruck
    1304           0 :         if (pCondition->count() == 3 &&
    1305           0 :             SQL_ISPUNCTUATION(pCondition->getChild(0),"(") &&
    1306           0 :             SQL_ISPUNCTUATION(pCondition->getChild(2),")"))
    1307             :         {
    1308           0 :             eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pCondition->getChild(1),nLevel,bHaving,bAddOrOnOneLine);
    1309             :         }
    1310             :         // oder Verknuepfung
    1311             :         // a searchcondition can only look like this: search_condition SQL_TOKEN_OR boolean_term
    1312           0 :         else if (SQL_ISRULE(pCondition,search_condition))
    1313             :         {
    1314           0 :             for (int i = 0; i < 3 && eErrorCode == eOk ; i+=2)
    1315             :             {
    1316           0 :                 const  ::connectivity::OSQLParseNode* pChild = pCondition->getChild(i);
    1317           0 :                 if ( SQL_ISRULE(pChild,search_condition) )
    1318           0 :                     eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pChild,nLevel,bHaving,bAddOrOnOneLine);
    1319             :                 else
    1320             :                 {
    1321           0 :                     eErrorCode = GetANDCriteria(_pView,_pSelectionBrw,pChild, nLevel,bHaving, i == 0 ? false : bAddOrOnOneLine);
    1322           0 :                     if ( !bAddOrOnOneLine)
    1323           0 :                         nLevel++;
    1324             :                 }
    1325             :             }
    1326             :         }
    1327             :         else
    1328           0 :             eErrorCode = GetANDCriteria( _pView,_pSelectionBrw,pCondition, nLevel, bHaving,bAddOrOnOneLine );
    1329             : 
    1330           0 :         return eErrorCode;
    1331             :     }
    1332             :     //--------------------------------------------------------------------------------------------------
    1333           0 :     bool CheckOrCriteria(const ::connectivity::OSQLParseNode* _pCondition,::connectivity::OSQLParseNode* _pFirstColumnRef)
    1334             :     {
    1335           0 :         bool bRet = true;
    1336           0 :         ::connectivity::OSQLParseNode* pFirstColumnRef = _pFirstColumnRef;
    1337           0 :         for (int i = 0; i < 3 && bRet; i+=2)
    1338             :         {
    1339           0 :             const  ::connectivity::OSQLParseNode* pChild = _pCondition->getChild(i);
    1340           0 :             if ( SQL_ISRULE(pChild,search_condition) )
    1341           0 :                 bRet = CheckOrCriteria(pChild,pFirstColumnRef);
    1342             :             else
    1343             :             {
    1344             :                 // this is a simple way to test columns are the same, may be we have to adjust this algo a little bit in future. :-)
    1345           0 :                 ::connectivity::OSQLParseNode* pSecondColumnRef = pChild->getByRule(::connectivity::OSQLParseNode::column_ref);
    1346           0 :                 if ( pFirstColumnRef && pSecondColumnRef )
    1347           0 :                     bRet = *pFirstColumnRef == *pSecondColumnRef;
    1348           0 :                 else if ( !pFirstColumnRef )
    1349           0 :                     pFirstColumnRef = pSecondColumnRef;
    1350             :             }
    1351             :         }
    1352           0 :         return bRet;
    1353             :     }
    1354             :     //--------------------------------------------------------------------------------------------------
    1355           0 :     SqlParseError GetANDCriteria(   OQueryDesignView* _pView,
    1356             :                                     OSelectionBrowseBox* _pSelectionBrw,
    1357             :                                     const  ::connectivity::OSQLParseNode * pCondition,
    1358             :                                     sal_uInt16& nLevel,
    1359             :                                     sal_Bool bHaving,
    1360             :                                     bool bAddOrOnOneLine)
    1361             :     {
    1362           0 :         const ::com::sun::star::lang::Locale    aLocale = _pView->getLocale();
    1363           0 :         const ::rtl::OUString sDecimal = _pView->getDecimalSeparator();
    1364             : 
    1365             :         // ich werde ein paar Mal einen gecasteten Pointer auf meinen ::com::sun::star::sdbcx::Container brauchen
    1366           0 :         OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
    1367           0 :         SqlParseError eErrorCode = eOk;
    1368             : 
    1369             :         // Runde Klammern
    1370           0 :         if (SQL_ISRULE(pCondition,boolean_primary))
    1371             :         {
    1372             :             // check if we have to put the or criteria on one line.
    1373           0 :             const  ::connectivity::OSQLParseNode* pSearchCondition = pCondition->getChild(1);
    1374           0 :             bool bMustAddOrOnOneLine = CheckOrCriteria(pSearchCondition,NULL);
    1375           0 :             if ( SQL_ISRULE( pSearchCondition, search_condition) ) // we have a or
    1376             :             {
    1377           0 :                 _pSelectionBrw->DuplicateConditionLevel( nLevel);
    1378           0 :                 eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSearchCondition->getChild(0), nLevel,bHaving,bMustAddOrOnOneLine );
    1379           0 :                 ++nLevel;
    1380           0 :                 eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSearchCondition->getChild(2), nLevel,bHaving,bMustAddOrOnOneLine );
    1381             :             }
    1382             :             else
    1383           0 :                 eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSearchCondition, nLevel,bHaving,bMustAddOrOnOneLine );
    1384             :         }
    1385             :         // Das erste Element ist (wieder) eine AND-Verknuepfung
    1386           0 :         else if ( SQL_ISRULE(pCondition,boolean_term) )
    1387             :         {
    1388             :             OSL_ENSURE(pCondition->count() == 3,"Illegal definifiton of boolean_term");
    1389           0 :             eErrorCode = GetANDCriteria(_pView,_pSelectionBrw,pCondition->getChild(0), nLevel,bHaving,bAddOrOnOneLine );
    1390           0 :             if ( eErrorCode == eOk )
    1391           0 :                 eErrorCode = GetANDCriteria(_pView,_pSelectionBrw,pCondition->getChild(2), nLevel,bHaving,bAddOrOnOneLine );
    1392             :         }
    1393           0 :         else if (SQL_ISRULE( pCondition, comparison_predicate))
    1394             :         {
    1395           0 :             eErrorCode = ComparisonPredicate(_pView,_pSelectionBrw,pCondition,nLevel,bHaving,bAddOrOnOneLine);
    1396             :         }
    1397           0 :         else if( SQL_ISRULE(pCondition,like_predicate) )
    1398             :         {
    1399           0 :             const  ::connectivity::OSQLParseNode* pValueExp = pCondition->getChild(0);
    1400           0 :             if (SQL_ISRULE(pValueExp, column_ref ) )
    1401             :             {
    1402           0 :                 ::rtl::OUString aColumnName;
    1403           0 :                 ::rtl::OUString aCondition;
    1404           0 :                 Reference< XConnection> xConnection = rController.getConnection();
    1405           0 :                 if ( xConnection.is() )
    1406             :                 {
    1407           0 :                     Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
    1408             :                     // the international doesn't matter I have a string
    1409             :                     pCondition->parseNodeToPredicateStr(aCondition,
    1410             :                                                         xConnection,
    1411             :                                                         rController.getNumberFormatter(),
    1412             :                                                         aLocale,
    1413           0 :                                                         static_cast<sal_Char>(sDecimal.toChar()),
    1414           0 :                                                         &rController.getParser().getContext());
    1415             : 
    1416             :                     pValueExp->parseNodeToPredicateStr( aColumnName,
    1417             :                                                         xConnection,
    1418             :                                                         rController.getNumberFormatter(),
    1419             :                                                         aLocale,
    1420           0 :                                                         static_cast<sal_Char>(sDecimal.toChar()),
    1421           0 :                                                         &rController.getParser().getContext());
    1422             : 
    1423             :                     // don't display the column name
    1424           0 :                     aCondition = aCondition.copy(aColumnName.getLength());
    1425           0 :                     aCondition = aCondition.trim();
    1426             :                 }
    1427             : 
    1428           0 :                 OTableFieldDescRef aDragLeft = new OTableFieldDesc();
    1429           0 :                 if ( eOk == ( eErrorCode = FillDragInfo(_pView,pValueExp,aDragLeft) ))
    1430             :                 {
    1431           0 :                     if ( bHaving )
    1432           0 :                         aDragLeft->SetGroupBy(sal_True);
    1433           0 :                     _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
    1434           0 :                 }
    1435             :             }
    1436           0 :             else if(SQL_ISRULEOR3(pValueExp, general_set_fct, set_fct_spec, position_exp)  ||
    1437           0 :                       SQL_ISRULEOR3(pValueExp, extract_exp, fold, char_substring_fct)       ||
    1438           0 :                       SQL_ISRULEOR2(pValueExp, length_exp, char_value_fct))
    1439             :             {
    1440             :                 AddFunctionCondition(   _pView,
    1441             :                                         _pSelectionBrw,
    1442             :                                         pCondition,
    1443             :                                         nLevel,
    1444             :                                         bHaving,
    1445           0 :                                         bAddOrOnOneLine);
    1446             :             }
    1447             :             else
    1448             :             {
    1449           0 :                 eErrorCode = eNoColumnInLike;
    1450           0 :                 String sError(ModuleRes(STR_QRY_LIKE_LEFT_NO_COLUMN));
    1451           0 :                 _pView->getController().appendError( sError );
    1452             :             }
    1453             :         }
    1454           0 :         else if(    SQL_ISRULEOR2(pCondition,test_for_null,in_predicate)
    1455           0 :                 ||  SQL_ISRULEOR2(pCondition,all_or_any_predicate,between_predicate))
    1456             :         {
    1457           0 :             if ( SQL_ISRULEOR2(pCondition->getChild(0), set_fct_spec , general_set_fct ) )
    1458             :             {
    1459             :                 AddFunctionCondition(   _pView,
    1460             :                                         _pSelectionBrw,
    1461             :                                         pCondition,
    1462             :                                         nLevel,
    1463             :                                         bHaving,
    1464           0 :                                         bAddOrOnOneLine);
    1465             :             }
    1466           0 :             else if ( SQL_ISRULE(pCondition->getChild(0), column_ref ) )
    1467             :             {
    1468             :                 // parse condition
    1469           0 :                 ::rtl::OUString sCondition = ParseCondition(rController,pCondition,sDecimal,aLocale,1);
    1470           0 :                 OTableFieldDescRef  aDragLeft = new OTableFieldDesc();
    1471           0 :                 if ( eOk == ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(0),aDragLeft)) )
    1472             :                 {
    1473           0 :                     if ( bHaving )
    1474           0 :                         aDragLeft->SetGroupBy(sal_True);
    1475           0 :                     _pSelectionBrw->AddCondition(aDragLeft, sCondition, nLevel,bAddOrOnOneLine);
    1476           0 :                 }
    1477             :             }
    1478             :             else
    1479             :             {
    1480             :                 // Funktions-Bedingung parsen
    1481           0 :                 ::rtl::OUString sCondition = ParseCondition(rController,pCondition,sDecimal,aLocale,1);
    1482           0 :                 Reference< XConnection> xConnection = rController.getConnection();
    1483           0 :                 Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
    1484             :                     // the international doesn't matter I have a string
    1485           0 :                 ::rtl::OUString sName;
    1486             :                 pCondition->getChild(0)->parseNodeToPredicateStr(sName,
    1487             :                                                     xConnection,
    1488             :                                                     rController.getNumberFormatter(),
    1489             :                                                     aLocale,
    1490           0 :                                                     static_cast<sal_Char>(sDecimal.toChar()),
    1491           0 :                                                     &rController.getParser().getContext());
    1492             : 
    1493           0 :                 OTableFieldDescRef aDragLeft = new OTableFieldDesc();
    1494           0 :                 aDragLeft->SetField(sName);
    1495           0 :                 aDragLeft->SetFunctionType(FKT_OTHER);
    1496             : 
    1497           0 :                 if ( bHaving )
    1498           0 :                     aDragLeft->SetGroupBy(sal_True);
    1499           0 :                 _pSelectionBrw->AddCondition(aDragLeft, sCondition, nLevel,bAddOrOnOneLine);
    1500             :             }
    1501             :         }
    1502           0 :         else if( SQL_ISRULEOR2(pCondition,existence_test,unique_test) )
    1503             :         {
    1504             :             // Funktions-Bedingung parsen
    1505           0 :             ::rtl::OUString aCondition = ParseCondition(rController,pCondition,sDecimal,aLocale,0);
    1506             : 
    1507           0 :             OTableFieldDescRef aDragLeft = new OTableFieldDesc();
    1508           0 :             aDragLeft->SetField(aCondition);
    1509           0 :             aDragLeft->SetFunctionType(FKT_CONDITION);
    1510             : 
    1511           0 :             eErrorCode = _pSelectionBrw->InsertField(aDragLeft,BROWSER_INVALIDID,sal_False,sal_True).is() ? eOk : eTooManyColumns;
    1512             :         }
    1513             :         else //! TODO not supported yet
    1514           0 :             eErrorCode = eStatementTooComplex;
    1515             :         // Fehler einfach weiterreichen.
    1516           0 :         return eErrorCode;
    1517             :     }
    1518             :     //------------------------------------------------------------------------------
    1519           0 :     SqlParseError AddFunctionCondition(OQueryDesignView* _pView,
    1520             :                             OSelectionBrowseBox* _pSelectionBrw,
    1521             :                             const ::connectivity::OSQLParseNode * pCondition,
    1522             :                             const sal_uInt16 nLevel,
    1523             :                             sal_Bool bHaving,
    1524             :                             bool bAddOrOnOneLine)
    1525             :     {
    1526           0 :         SqlParseError eErrorCode = eOk;
    1527           0 :         OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
    1528             : 
    1529           0 :         OSQLParseNode* pFunction = pCondition->getChild(0);
    1530             : 
    1531             :         OSL_ENSURE(SQL_ISRULEOR3(pFunction, general_set_fct, set_fct_spec, position_exp)  ||
    1532             :                      SQL_ISRULEOR3(pFunction, extract_exp, fold, char_substring_fct)      ||
    1533             :                      SQL_ISRULEOR2(pFunction,length_exp,char_value_fct),
    1534             :                    "Illegal call!");
    1535           0 :         ::rtl::OUString aCondition;
    1536           0 :         OTableFieldDescRef aDragLeft = new OTableFieldDesc();
    1537             : 
    1538           0 :         ::rtl::OUString aColumnName;
    1539           0 :         Reference< XConnection> xConnection = rController.getConnection();
    1540           0 :         if(xConnection.is())
    1541             :         {
    1542           0 :             Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
    1543             :             pCondition->parseNodeToPredicateStr(aCondition,
    1544             :                                                 xConnection,
    1545             :                                                 rController.getNumberFormatter(),
    1546             :                                                 _pView->getLocale(),
    1547           0 :                                                 static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
    1548           0 :                                                 &rController.getParser().getContext());
    1549             : 
    1550             :             pFunction->parseNodeToStr(  aColumnName,
    1551             :                                         xConnection,
    1552           0 :                                         &rController.getParser().getContext(),
    1553             :                                         sal_True,
    1554           0 :                                         sal_True); // quote is to true because we need quoted elements inside the function
    1555             :             // don't display the column name
    1556           0 :             aCondition = aCondition.copy(aColumnName.getLength());
    1557           0 :             aCondition = aCondition.trim();
    1558           0 :             if ( aCondition.indexOf('=',0) == 0 ) // ignore the equal sign
    1559           0 :                 aCondition = aCondition.copy(1);
    1560             : 
    1561             : 
    1562           0 :             if ( SQL_ISRULE(pFunction, general_set_fct ) )
    1563             :             {
    1564           0 :                 sal_Int32 nFunctionType = FKT_AGGREGATE;
    1565           0 :                 OSQLParseNode* pParamNode = pFunction->getChild(pFunction->count()-2);
    1566           0 :                 if ( pParamNode && pParamNode->getTokenValue().toChar() == '*' )
    1567             :                 {
    1568           0 :                     OJoinTableView::OTableWindowMap* pTabList = _pView->getTableView()->GetTabWinMap();
    1569           0 :                     OJoinTableView::OTableWindowMap::iterator aIter = pTabList->begin();
    1570           0 :                     OJoinTableView::OTableWindowMap::iterator aTabEnd = pTabList->end();
    1571           0 :                     for(;aIter != aTabEnd;++aIter)
    1572             :                     {
    1573           0 :                         OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second);
    1574           0 :                         if (pTabWin->ExistsField( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), aDragLeft ))
    1575             :                         {
    1576           0 :                             aDragLeft->SetAlias(String());
    1577           0 :                             aDragLeft->SetTable(String());
    1578           0 :                             break;
    1579             :                         }
    1580             :                     }
    1581             :                 }
    1582           0 :                 else if( eOk != ( eErrorCode = FillDragInfo(_pView,pParamNode,aDragLeft))
    1583           0 :                         && SQL_ISRULE(pParamNode,num_value_exp) )
    1584             :                 {
    1585           0 :                     ::rtl::OUString sParameterValue;
    1586             :                     pParamNode->parseNodeToStr( sParameterValue,
    1587             :                                                 xConnection,
    1588           0 :                                                 &rController.getParser().getContext());
    1589           0 :                     nFunctionType |= FKT_NUMERIC;
    1590           0 :                     aDragLeft->SetField(sParameterValue);
    1591           0 :                     eErrorCode = eOk;
    1592             :                 }
    1593           0 :                 aDragLeft->SetFunctionType(nFunctionType);
    1594           0 :                 if ( bHaving )
    1595           0 :                     aDragLeft->SetGroupBy(sal_True);
    1596           0 :                 sal_Int32 nIndex = 0;
    1597           0 :                 aDragLeft->SetFunction(aColumnName.getToken(0,'(',nIndex));
    1598             :             }
    1599             :             else
    1600             :             {
    1601             :                 // bei unbekannten Funktionen wird der gesamte Text in das Field gechrieben
    1602           0 :                 aDragLeft->SetField(aColumnName);
    1603           0 :                 if(bHaving)
    1604           0 :                     aDragLeft->SetGroupBy(sal_True);
    1605           0 :                 aDragLeft->SetFunctionType(FKT_OTHER|FKT_NUMERIC);
    1606             :             }
    1607           0 :             _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
    1608             :         }
    1609             : 
    1610           0 :         return eErrorCode;
    1611             :     }
    1612             :     //------------------------------------------------------------------------------
    1613           0 :     SqlParseError ComparisonPredicate(OQueryDesignView* _pView,
    1614             :                             OSelectionBrowseBox* _pSelectionBrw,
    1615             :                             const ::connectivity::OSQLParseNode * pCondition,
    1616             :                             const sal_uInt16 nLevel,
    1617             :                             sal_Bool bHaving
    1618             :                             ,bool bAddOrOnOneLine)
    1619             :     {
    1620           0 :         SqlParseError eErrorCode = eOk;
    1621           0 :         OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
    1622             : 
    1623             :         OSL_ENSURE(SQL_ISRULE( pCondition, comparison_predicate),"ComparisonPredicate: pCondition ist kein ComparisonPredicate");
    1624           0 :         if ( SQL_ISRULE(pCondition->getChild(0), column_ref )
    1625           0 :             || SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref) )
    1626             :         {
    1627           0 :             ::rtl::OUString aCondition;
    1628           0 :             OTableFieldDescRef aDragLeft = new OTableFieldDesc();
    1629             : 
    1630           0 :             if ( SQL_ISRULE(pCondition->getChild(0), column_ref ) && SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref ) )
    1631             :             {
    1632           0 :                 OTableFieldDescRef aDragRight = new OTableFieldDesc();
    1633           0 :                 if (eOk != ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(0),aDragLeft)) ||
    1634           0 :                     eOk != ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(2),aDragRight)))
    1635           0 :                     return eErrorCode;
    1636             : 
    1637             :                 OQueryTableConnection* pConn = static_cast<OQueryTableConnection*>(
    1638           0 :                                                     _pView->getTableView()->GetTabConn(static_cast<OQueryTableWindow*>(aDragLeft->GetTabWindow()),
    1639           0 :                                                                                        static_cast<OQueryTableWindow*>(aDragRight->GetTabWindow()),
    1640           0 :                                                                                        true));
    1641           0 :                 if ( pConn )
    1642             :                 {
    1643           0 :                     OConnectionLineDataVec* pLineDataList = pConn->GetData()->GetConnLineDataList();
    1644           0 :                     OConnectionLineDataVec::iterator aIter = pLineDataList->begin();
    1645           0 :                     OConnectionLineDataVec::iterator aEnd = pLineDataList->end();
    1646           0 :                     for(;aIter != aEnd;++aIter)
    1647             :                     {
    1648           0 :                         if((*aIter)->GetSourceFieldName() == aDragLeft->GetField() ||
    1649           0 :                            (*aIter)->GetDestFieldName() == aDragLeft->GetField() )
    1650           0 :                             break;
    1651             :                     }
    1652           0 :                     if(aIter != aEnd)
    1653           0 :                         return eOk;
    1654           0 :                 }
    1655             :             }
    1656             : 
    1657           0 :             sal_uInt32 nPos = 0;
    1658           0 :             if(SQL_ISRULE(pCondition->getChild(0), column_ref ))
    1659             :             {
    1660           0 :                 nPos = 0;
    1661           0 :                 sal_uInt32 i=1;
    1662             : 
    1663             :                 // don't display the equal
    1664           0 :                 if (pCondition->getChild(i)->getNodeType() == SQL_NODE_EQUAL)
    1665           0 :                     i++;
    1666             : 
    1667             :                 // Bedingung parsen
    1668             :                 aCondition = ParseCondition(rController
    1669             :                                             ,pCondition
    1670             :                                             ,_pView->getDecimalSeparator()
    1671             :                                             ,_pView->getLocale()
    1672           0 :                                             ,i);
    1673             :             }
    1674           0 :             else if( SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref ) )
    1675             :             {
    1676           0 :                 nPos = pCondition->count()-1;
    1677             : 
    1678           0 :                 sal_Int32 i = static_cast<sal_Int32>(pCondition->count() - 2);
    1679           0 :                 switch (pCondition->getChild(i)->getNodeType())
    1680             :                 {
    1681             :                     case SQL_NODE_EQUAL:
    1682             :                         // don't display the equal
    1683           0 :                         i--;
    1684           0 :                         break;
    1685             :                     case SQL_NODE_LESS:
    1686             :                         // take the opposite as we change the order
    1687           0 :                         i--;
    1688           0 :                         aCondition = aCondition + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">"));
    1689           0 :                         break;
    1690             :                     case SQL_NODE_LESSEQ:
    1691             :                         // take the opposite as we change the order
    1692           0 :                         i--;
    1693           0 :                         aCondition = aCondition + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(">="));
    1694           0 :                         break;
    1695             :                     case SQL_NODE_GREAT:
    1696             :                         // take the opposite as we change the order
    1697           0 :                         i--;
    1698           0 :                         aCondition = aCondition + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<"));
    1699           0 :                         break;
    1700             :                     case SQL_NODE_GREATEQ:
    1701             :                         // take the opposite as we change the order
    1702           0 :                         i--;
    1703           0 :                         aCondition = aCondition + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("<="));
    1704           0 :                         break;
    1705             :                     default:
    1706           0 :                         break;
    1707             :                 }
    1708             : 
    1709             :                 // go backward
    1710           0 :                 Reference< XConnection> xConnection = rController.getConnection();
    1711           0 :                 if(xConnection.is())
    1712             :                 {
    1713           0 :                     Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
    1714           0 :                     for (; i >= 0; i--)
    1715             :                         pCondition->getChild(i)->parseNodeToPredicateStr(aCondition,
    1716             :                                                 xConnection,
    1717             :                                                 rController.getNumberFormatter(),
    1718             :                                                 _pView->getLocale(),
    1719           0 :                                                 static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
    1720           0 :                                                 &rController.getParser().getContext());
    1721           0 :                 }
    1722             :             }
    1723             :             // else ???
    1724             : 
    1725             : 
    1726           0 :             if( eOk == ( eErrorCode = FillDragInfo(_pView,pCondition->getChild(nPos),aDragLeft)))
    1727             :             {
    1728           0 :                 if(bHaving)
    1729           0 :                     aDragLeft->SetGroupBy(sal_True);
    1730           0 :                 _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
    1731           0 :             }
    1732             :         }
    1733           0 :         else if( SQL_ISRULEOR2(pCondition->getChild(0), set_fct_spec , general_set_fct ) )
    1734             :         {
    1735             :             AddFunctionCondition(   _pView,
    1736             :                                     _pSelectionBrw,
    1737             :                                     pCondition,
    1738             :                                     nLevel,
    1739             :                                     bHaving,
    1740           0 :                                     bAddOrOnOneLine);
    1741             :         }
    1742             :         else // kann sich nur um einen Expr. Ausdruck handeln
    1743             :         {
    1744           0 :             ::rtl::OUString aName,aCondition;
    1745             : 
    1746           0 :             ::connectivity::OSQLParseNode *pLhs = pCondition->getChild(0);
    1747           0 :             ::connectivity::OSQLParseNode *pRhs = pCondition->getChild(2);
    1748             :             // Feldnamen
    1749           0 :             Reference< XConnection> xConnection = rController.getConnection();
    1750           0 :             if(xConnection.is())
    1751             :             {
    1752             :                 pLhs->parseNodeToStr(aName,
    1753             :                                      xConnection,
    1754           0 :                                      &rController.getParser().getContext(),
    1755           0 :                                      sal_True);
    1756             :                 // Kriterium
    1757           0 :                 aCondition = pCondition->getChild(1)->getTokenValue();
    1758             :                 pRhs->parseNodeToPredicateStr(aCondition,
    1759             :                                                             xConnection,
    1760             :                                                             rController.getNumberFormatter(),
    1761             :                                                             _pView->getLocale(),
    1762           0 :                                                             static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
    1763           0 :                                                             &rController.getParser().getContext());
    1764             :             }
    1765             : 
    1766           0 :             OTableFieldDescRef aDragLeft = new OTableFieldDesc();
    1767           0 :             aDragLeft->SetField(aName);
    1768           0 :             aDragLeft->SetFunctionType(FKT_OTHER|FKT_NUMERIC);
    1769             :             // und anh"angen
    1770           0 :             _pSelectionBrw->AddCondition(aDragLeft, aCondition, nLevel,bAddOrOnOneLine);
    1771             :         }
    1772           0 :         return eErrorCode;
    1773             :     }
    1774             : 
    1775             :     //------------------------------------------------------------------------------
    1776             :     namespace
    1777             :     {
    1778           0 :         OQueryTableWindow* lcl_findColumnInTables( const ::rtl::OUString& _rColumName, const OJoinTableView::OTableWindowMap& _rTabList, OTableFieldDescRef& _rInfo )
    1779             :         {
    1780           0 :             OJoinTableView::OTableWindowMap::const_iterator aIter = _rTabList.begin();
    1781           0 :             OJoinTableView::OTableWindowMap::const_iterator aEnd = _rTabList.end();
    1782           0 :             for ( ; aIter != aEnd; ++aIter )
    1783             :             {
    1784           0 :                 OQueryTableWindow* pTabWin = static_cast< OQueryTableWindow* >( aIter->second );
    1785           0 :                 if ( pTabWin && pTabWin->ExistsField( _rColumName, _rInfo ) )
    1786           0 :                     return pTabWin;
    1787             :             }
    1788           0 :             return NULL;
    1789             :         }
    1790             :     }
    1791             : 
    1792             :     //------------------------------------------------------------------------------
    1793           0 :     void InsertColumnRef(const OQueryDesignView* _pView,
    1794             :                         const ::connectivity::OSQLParseNode * pColumnRef,
    1795             :                         ::rtl::OUString& aColumnName,
    1796             :                         const ::rtl::OUString& aColumnAlias,
    1797             :                         ::rtl::OUString& aTableRange,
    1798             :                         OTableFieldDescRef& _raInfo,
    1799             :                         OJoinTableView::OTableWindowMap* pTabList)
    1800             :     {
    1801             : 
    1802             :         // Tabellennamen zusammen setzen
    1803           0 :         ::connectivity::OSQLParseTreeIterator& rParseIter = static_cast<OQueryController&>(_pView->getController()).getParseIterator();
    1804           0 :         rParseIter.getColumnRange( pColumnRef, aColumnName, aTableRange );
    1805             : 
    1806           0 :         sal_Bool bFound(sal_False);
    1807             :         OSL_ENSURE(!aColumnName.isEmpty(),"Columnname darf nicht leer sein");
    1808           0 :         if (aTableRange.isEmpty())
    1809             :         {
    1810             :             // SELECT column, ...
    1811           0 :             bFound = NULL != lcl_findColumnInTables( aColumnName, *pTabList, _raInfo );
    1812           0 :             if ( bFound && ( aColumnName.toChar() != '*' ) )
    1813           0 :                 _raInfo->SetFieldAlias(aColumnAlias);
    1814             :         }
    1815             :         else
    1816             :         {
    1817             :             // SELECT range.column, ...
    1818           0 :             OQueryTableWindow* pTabWin = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable(aTableRange);
    1819             : 
    1820           0 :             if (pTabWin && pTabWin->ExistsField(aColumnName, _raInfo))
    1821             :             {
    1822           0 :                 if(aColumnName.toChar() != '*')
    1823           0 :                     _raInfo->SetFieldAlias(aColumnAlias);
    1824           0 :                 bFound = sal_True;
    1825             :             }
    1826             :         }
    1827           0 :         if (!bFound)
    1828             :         {
    1829           0 :             _raInfo->SetTable(::rtl::OUString());
    1830           0 :             _raInfo->SetAlias(::rtl::OUString());
    1831           0 :             _raInfo->SetField(aColumnName);
    1832           0 :             _raInfo->SetFieldAlias(aColumnAlias);   // nyi : hier ein fortlaufendes Expr_1, Expr_2 ...
    1833           0 :             _raInfo->SetFunctionType(FKT_OTHER);
    1834             :         }
    1835           0 :     }
    1836             :     //-----------------------------------------------------------------------------
    1837           0 :     sal_Bool checkJoinConditions(   const OQueryDesignView* _pView,
    1838             :                                     const ::connectivity::OSQLParseNode* _pNode )
    1839             :     {
    1840           0 :         const ::connectivity::OSQLParseNode* pJoinNode = NULL;
    1841           0 :         sal_Bool bRet = sal_True;
    1842           0 :         if (SQL_ISRULE(_pNode,qualified_join))
    1843           0 :             pJoinNode = _pNode;
    1844           0 :         else if (SQL_ISRULE(_pNode,table_ref)
    1845           0 :                 &&  _pNode->count() == 3
    1846           0 :                 &&  SQL_ISPUNCTUATION(_pNode->getChild(0),"(")
    1847           0 :                 &&  SQL_ISPUNCTUATION(_pNode->getChild(2),")") ) // '(' joined_table ')'
    1848           0 :             pJoinNode = _pNode->getChild(1);
    1849           0 :         else if (! ( SQL_ISRULE(_pNode, table_ref) && _pNode->count() == 2) ) // table_node table_primary_as_range_column
    1850           0 :             bRet = sal_False;
    1851             : 
    1852           0 :         if (pJoinNode && !InsertJoin(_pView,pJoinNode))
    1853           0 :             bRet = sal_False;
    1854           0 :         return bRet;
    1855             :     }
    1856             :     //-----------------------------------------------------------------------------
    1857           0 :     sal_Bool InsertJoin(const OQueryDesignView* _pView,
    1858             :                         const ::connectivity::OSQLParseNode *pNode)
    1859             :     {
    1860             :         OSL_ENSURE( SQL_ISRULE( pNode, qualified_join ) || SQL_ISRULE( pNode, joined_table ) || SQL_ISRULE( pNode, cross_union ),
    1861             :             "OQueryDesignView::InsertJoin: Fehler im Parse Tree");
    1862             : 
    1863           0 :         if (SQL_ISRULE(pNode,joined_table))
    1864           0 :             return InsertJoin(_pView,pNode->getChild(1));
    1865             : 
    1866             :         // first check the left and right side
    1867           0 :         const ::connectivity::OSQLParseNode* pRightTableRef = pNode->getChild(3); // table_ref
    1868           0 :         if ( SQL_ISRULE(pNode, qualified_join) && SQL_ISTOKEN(pNode->getChild(1),NATURAL) )
    1869           0 :             pRightTableRef = pNode->getChild(4); // table_ref
    1870             : 
    1871           0 :         if ( !checkJoinConditions(_pView,pNode->getChild(0)) || !checkJoinConditions(_pView,pRightTableRef))
    1872           0 :             return sal_False;
    1873             : 
    1874             :         // named column join wird sp�ter vieleicht noch implementiert
    1875             :         // SQL_ISRULE(pNode->getChild(4),named_columns_join)
    1876           0 :         EJoinType eJoinType = INNER_JOIN;
    1877           0 :         bool bNatural = false;
    1878           0 :         if ( SQL_ISRULE(pNode, qualified_join) )
    1879             :         {
    1880           0 :             ::connectivity::OSQLParseNode* pJoinType = pNode->getChild(1); // join_type
    1881           0 :             if ( SQL_ISTOKEN(pJoinType,NATURAL) )
    1882             :             {
    1883           0 :                 bNatural = true;
    1884           0 :                 pJoinType = pNode->getChild(2);
    1885             :             }
    1886             : 
    1887           0 :             if (SQL_ISRULE(pJoinType,join_type) && (!pJoinType->count() || SQL_ISTOKEN(pJoinType->getChild(0),INNER)))
    1888             :             {
    1889           0 :                 eJoinType = INNER_JOIN;
    1890             :             }
    1891             :             else
    1892             :             {
    1893           0 :                 if (SQL_ISRULE(pJoinType,join_type))       // eine Ebene tiefer
    1894           0 :                     pJoinType = pJoinType->getChild(0);
    1895             : 
    1896           0 :                 if (SQL_ISTOKEN(pJoinType->getChild(0),LEFT))
    1897           0 :                     eJoinType = LEFT_JOIN;
    1898           0 :                 else if(SQL_ISTOKEN(pJoinType->getChild(0),RIGHT))
    1899           0 :                     eJoinType = RIGHT_JOIN;
    1900             :                 else
    1901           0 :                     eJoinType = FULL_JOIN;
    1902             :             }
    1903           0 :             if ( SQL_ISRULE(pNode->getChild(4),join_condition) )
    1904             :             {
    1905           0 :                 if ( InsertJoinConnection(_pView,pNode->getChild(4)->getChild(1), eJoinType,pNode->getChild(0),pRightTableRef) != eOk )
    1906           0 :                     return sal_False;
    1907             :             }
    1908             :         }
    1909           0 :         else if ( SQL_ISRULE(pNode, cross_union) )
    1910             :         {
    1911           0 :             eJoinType = CROSS_JOIN;
    1912           0 :             pRightTableRef = pNode->getChild(pNode->count() - 1);
    1913             :         }
    1914             :         else
    1915           0 :             return sal_False;
    1916             : 
    1917           0 :         if ( eJoinType == CROSS_JOIN || bNatural )
    1918             :         {
    1919             : 
    1920           0 :             OQueryTableWindow*  pLeftWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pNode->getChild(0)) );
    1921           0 :             OQueryTableWindow*  pRightWindow = static_cast<OQueryTableView*>(_pView->getTableView())->FindTable( getTableRange(_pView,pRightTableRef) );
    1922             :             OSL_ENSURE(pLeftWindow && pRightWindow,"Table Windows could not be found!");
    1923           0 :             if ( !pLeftWindow || !pRightWindow )
    1924           0 :                 return sal_False;
    1925             : 
    1926           0 :             OTableFieldDescRef aDragLeft  = new OTableFieldDesc();
    1927           0 :             aDragLeft->SetTabWindow(pLeftWindow);
    1928           0 :             aDragLeft->SetTable(pLeftWindow->GetTableName());
    1929           0 :             aDragLeft->SetAlias(pLeftWindow->GetAliasName());
    1930             : 
    1931           0 :             OTableFieldDescRef aDragRight = new OTableFieldDesc();
    1932           0 :             aDragRight->SetTabWindow(pRightWindow);
    1933           0 :             aDragRight->SetTable(pRightWindow->GetTableName());
    1934           0 :             aDragRight->SetAlias(pRightWindow->GetAliasName());
    1935             : 
    1936           0 :             insertConnection(_pView,eJoinType,aDragLeft,aDragRight,bNatural);
    1937             :         }
    1938             : 
    1939             : 
    1940           0 :         return sal_True;
    1941             :     }
    1942             :     //------------------------------------------------------------------------------
    1943           0 :     void insertUnUsedFields(OQueryDesignView* _pView,OSelectionBrowseBox* _pSelectionBrw)
    1944             :     {
    1945             :         // now we have to insert the fields which aren't in the statement
    1946           0 :         OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
    1947           0 :         OTableFields& rUnUsedFields = rController.getUnUsedFields();
    1948           0 :         OTableFields::iterator aEnd = rUnUsedFields.end();
    1949           0 :         for(OTableFields::iterator aIter = rUnUsedFields.begin();aIter != aEnd;++aIter)
    1950           0 :             if(_pSelectionBrw->InsertField(*aIter,BROWSER_INVALIDID,sal_False,sal_False).is())
    1951           0 :                 (*aIter) = NULL;
    1952           0 :         OTableFields().swap( rUnUsedFields );
    1953           0 :     }
    1954             : 
    1955             :     //------------------------------------------------------------------------------
    1956           0 :     SqlParseError InitFromParseNodeImpl(OQueryDesignView* _pView,OSelectionBrowseBox* _pSelectionBrw)
    1957             :     {
    1958           0 :         SqlParseError eErrorCode = eOk;
    1959             : 
    1960           0 :         OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
    1961             : 
    1962           0 :         _pSelectionBrw->PreFill();
    1963           0 :         _pSelectionBrw->SetReadOnly(rController.isReadOnly());
    1964           0 :         _pSelectionBrw->Fill();
    1965             : 
    1966             : 
    1967           0 :         ::connectivity::OSQLParseTreeIterator& aIterator = rController.getParseIterator();
    1968           0 :         const ::connectivity::OSQLParseNode* pParseTree = aIterator.getParseTree();
    1969             : 
    1970             :         do
    1971             :         {
    1972           0 :             if ( !pParseTree )
    1973             :             {
    1974             :                 // now we have to insert the fields which aren't in the statement
    1975           0 :                 insertUnUsedFields(_pView,_pSelectionBrw);
    1976             :                 break;
    1977             :             }
    1978             : 
    1979           0 :             if ( !rController.isEsacpeProcessing() ) // not allowed in this mode
    1980             :             {
    1981           0 :                 eErrorCode = eNativeMode;
    1982             :                 break;
    1983             :             }
    1984             : 
    1985           0 :             if ( !( SQL_ISRULE( pParseTree, select_statement ) ) )
    1986             :             {
    1987           0 :                 eErrorCode = eNoSelectStatement;
    1988             :                 break;
    1989             :             }
    1990             : 
    1991           0 :             const OSQLParseNode* pTableExp = pParseTree->getChild(3);
    1992           0 :             if ( pTableExp->getChild(6)->count() > 0 || pTableExp->getChild(7)->count() > 0 || pTableExp->getChild(8)->count() > 0)
    1993             :             {
    1994           0 :                 eErrorCode = eStatementTooComplex;
    1995             :                 break;
    1996             :             }
    1997             : 
    1998           0 :             Reference< XConnection> xConnection = rController.getConnection();
    1999           0 :             if ( !xConnection.is() )
    2000             :             {
    2001             :                 OSL_FAIL( "InitFromParseNodeImpl: no connection? no connection!" );
    2002             :                 break;
    2003             :             }
    2004             : 
    2005           0 :             const OSQLTables& aMap = aIterator.getTables();
    2006           0 :             ::comphelper::UStringMixLess aTmp(aMap.key_comp());
    2007           0 :             ::comphelper::UStringMixEqual aKeyComp( aTmp.isCaseSensitive() );
    2008             : 
    2009           0 :             Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
    2010             :             try
    2011             :             {
    2012           0 :                 sal_Int32 nMax = xMetaData->getMaxTablesInSelect();
    2013           0 :                 if ( nMax && nMax < (sal_Int32)aMap.size() )
    2014             :                 {
    2015           0 :                     eErrorCode = eTooManyTables;
    2016             :                     break;
    2017             :                 }
    2018             : 
    2019           0 :                 ::rtl::OUString sComposedName;
    2020           0 :                 ::rtl::OUString sAlias;
    2021             : 
    2022           0 :                 OQueryTableView* pTableView = static_cast<OQueryTableView*>(_pView->getTableView());
    2023           0 :                 pTableView->clearLayoutInformation();
    2024           0 :                 OSQLTables::const_iterator aIter = aMap.begin();
    2025           0 :                 OSQLTables::const_iterator aEnd = aMap.end();
    2026           0 :                 for(;aIter != aEnd;++aIter)
    2027             :                 {
    2028           0 :                     OSQLTable xTable = aIter->second;
    2029           0 :                     Reference< XPropertySet > xTableProps( xTable, UNO_QUERY_THROW );
    2030             : 
    2031           0 :                     sAlias = aIter->first;
    2032             : 
    2033             :                     // check whether this is a query
    2034           0 :                     Reference< XPropertySetInfo > xPSI = xTableProps->getPropertySetInfo();
    2035           0 :                     bool bIsQuery = xPSI.is() && xPSI->hasPropertyByName( PROPERTY_COMMAND );
    2036             : 
    2037           0 :                     if ( bIsQuery )
    2038           0 :                         OSL_VERIFY( xTableProps->getPropertyValue( PROPERTY_NAME ) >>= sComposedName );
    2039             :                     else
    2040             :                     {
    2041           0 :                         sComposedName = ::dbtools::composeTableName( xMetaData, xTableProps, ::dbtools::eInDataManipulation, false, false, false );
    2042             : 
    2043             :                         // if the alias is the complete (composed) table, then shorten it
    2044           0 :                         if ( aKeyComp( sComposedName, aIter->first ) )
    2045             :                         {
    2046           0 :                             ::rtl::OUString sCatalog, sSchema, sTable;
    2047           0 :                             ::dbtools::qualifiedNameComponents( xMetaData, sComposedName, sCatalog, sSchema, sTable, ::dbtools::eInDataManipulation );
    2048           0 :                             sAlias = sTable;
    2049             :                         }
    2050             :                     }
    2051             : 
    2052             :                     // find the existent window for this alias
    2053           0 :                     OQueryTableWindow* pExistentWin = pTableView->FindTable( sAlias );
    2054           0 :                     if ( !pExistentWin )
    2055             :                     {
    2056           0 :                         pTableView->AddTabWin( sComposedName, sAlias, sal_False );  // don't create data here
    2057             :                     }
    2058             :                     else
    2059             :                     {
    2060             :                         // there already exists a window for this alias ....
    2061           0 :                         if ( !aKeyComp( pExistentWin->GetData()->GetComposedName(), sComposedName ) )
    2062             :                             // ... but for another complete table name -> new window
    2063           0 :                             pTableView->AddTabWin(sComposedName, sAlias);
    2064             :                     }
    2065           0 :                 }
    2066             : 
    2067             :                 // now delete the data for which we haven't any tablewindow
    2068           0 :                 OJoinTableView::OTableWindowMap aTableMap(*pTableView->GetTabWinMap());
    2069           0 :                 OJoinTableView::OTableWindowMap::iterator aIterTableMap = aTableMap.begin();
    2070           0 :                 OJoinTableView::OTableWindowMap::iterator aIterTableEnd = aTableMap.end();
    2071           0 :                 for(;aIterTableMap != aIterTableEnd;++aIterTableMap)
    2072             :                 {
    2073           0 :                     if(aMap.find(aIterTableMap->second->GetComposedName())  == aMap.end() &&
    2074           0 :                         aMap.find(aIterTableMap->first)                     == aMap.end())
    2075           0 :                         pTableView->RemoveTabWin(aIterTableMap->second);
    2076             :                 }
    2077             : 
    2078           0 :                 if ( eOk == (eErrorCode = FillOuterJoins(_pView,pTableExp->getChild(0)->getChild(1))) )
    2079             :                 {
    2080             :                     // check if we have a distinct statement
    2081           0 :                     if(SQL_ISTOKEN(pParseTree->getChild(1),DISTINCT))
    2082             :                     {
    2083           0 :                         rController.setDistinct(sal_True);
    2084           0 :                         rController.InvalidateFeature(SID_QUERY_DISTINCT_VALUES);
    2085             :                     }
    2086           0 :                     if ( (eErrorCode = InstallFields(_pView,pParseTree, pTableView->GetTabWinMap())) == eOk )
    2087             :                     {
    2088             :                         // GetSelectionCriteria must be called before GetHavingCriteria
    2089           0 :                         sal_uInt16 nLevel=0;
    2090             : 
    2091           0 :                         if ( eOk == (eErrorCode = GetSelectionCriteria(_pView,_pSelectionBrw,pParseTree,nLevel)) )
    2092             :                         {
    2093           0 :                             if ( eOk == (eErrorCode = GetGroupCriteria(_pView,_pSelectionBrw,pParseTree)) )
    2094             :                             {
    2095           0 :                                 if ( eOk == (eErrorCode = GetHavingCriteria(_pView,_pSelectionBrw,pParseTree,nLevel)) )
    2096             :                                 {
    2097           0 :                                     if ( eOk == (eErrorCode = GetOrderCriteria(_pView,_pSelectionBrw,pParseTree)) )
    2098           0 :                                         insertUnUsedFields(_pView,_pSelectionBrw);
    2099             :                                 }
    2100             :                             }
    2101             :                         }
    2102             :                     }
    2103           0 :                 }
    2104             :             }
    2105           0 :             catch(SQLException&)
    2106             :             {
    2107             :                 OSL_FAIL("getMaxTablesInSelect!");
    2108           0 :             }
    2109             :         }
    2110             :         while ( false );
    2111             : 
    2112             :         // Durch das Neuerzeugen wurden wieder Undo-Actions in den Manager gestellt
    2113           0 :         rController.ClearUndoManager();
    2114           0 :         _pSelectionBrw->Invalidate();
    2115           0 :         return eErrorCode;
    2116             :     }
    2117             :     //------------------------------------------------------------------------------
    2118             :     /** fillSelectSubList
    2119             :         @return
    2120             :             <TRUE/> when columns could be inserted otherwise <FALSE/>
    2121             :     */
    2122             :     //------------------------------------------------------------------------------
    2123           0 :     SqlParseError fillSelectSubList(    OQueryDesignView* _pView,
    2124             :                                 OJoinTableView::OTableWindowMap* _pTabList)
    2125             :     {
    2126           0 :         SqlParseError eErrorCode = eOk;
    2127           0 :         sal_Bool bFirstField = sal_True;
    2128           0 :         ::rtl::OUString sAsterix(RTL_CONSTASCII_USTRINGPARAM("*"));
    2129           0 :         OJoinTableView::OTableWindowMap::iterator aIter = _pTabList->begin();
    2130           0 :         OJoinTableView::OTableWindowMap::iterator aEnd = _pTabList->end();
    2131           0 :         for(;aIter != aEnd && eOk == eErrorCode ;++aIter)
    2132             :         {
    2133           0 :             OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second);
    2134           0 :             OTableFieldDescRef  aInfo = new OTableFieldDesc();
    2135           0 :             if (pTabWin->ExistsField( sAsterix, aInfo ))
    2136             :             {
    2137           0 :                 eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
    2138           0 :                 bFirstField = sal_False;
    2139             :             }
    2140           0 :         }
    2141           0 :         return eErrorCode;
    2142             :     }
    2143             :     //------------------------------------------------------------------------------
    2144           0 :     SqlParseError InstallFields(OQueryDesignView* _pView,
    2145             :                                 const ::connectivity::OSQLParseNode* pNode,
    2146             :                                 OJoinTableView::OTableWindowMap* pTabList )
    2147             :     {
    2148           0 :         if( pNode==0 || !SQL_ISRULE(pNode,select_statement))
    2149           0 :             return eNoSelectStatement;
    2150             : 
    2151           0 :         ::connectivity::OSQLParseNode* pParseTree = pNode->getChild(2); // selection
    2152           0 :         sal_Bool bFirstField = sal_True;    // bei der Initialisierung mu� auf alle Faelle das erste Feld neu aktiviert werden
    2153             : 
    2154           0 :         SqlParseError eErrorCode = eOk;
    2155             : 
    2156           0 :         if ( pParseTree->isRule() && SQL_ISPUNCTUATION(pParseTree->getChild(0),"*") )
    2157             :         {
    2158             :             // SELECT * ...
    2159           0 :             eErrorCode = fillSelectSubList(_pView,pTabList);
    2160             :         }
    2161           0 :         else if (SQL_ISRULE(pParseTree,scalar_exp_commalist) )
    2162             :         {
    2163             :             // SELECT column, ...
    2164           0 :             OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
    2165           0 :             Reference< XConnection> xConnection = rController.getConnection();
    2166             : 
    2167           0 :             ::rtl::OUString aColumnName,aTableRange;
    2168           0 :             for (sal_uInt32 i = 0; i < pParseTree->count() && eOk == eErrorCode ; ++i)
    2169             :             {
    2170           0 :                 ::connectivity::OSQLParseNode * pColumnRef = pParseTree->getChild(i);
    2171             : 
    2172             :                 do {
    2173             : 
    2174           0 :                 if ( SQL_ISRULE(pColumnRef,select_sublist) )
    2175             :                 {
    2176           0 :                      eErrorCode = fillSelectSubList(_pView,pTabList);
    2177           0 :                      break;
    2178             :                 }
    2179             : 
    2180           0 :                 if ( SQL_ISRULE(pColumnRef,derived_column) )
    2181             :                 {
    2182           0 :                     ::rtl::OUString aColumnAlias(rController.getParseIterator().getColumnAlias(pColumnRef)); // kann leer sein
    2183           0 :                     pColumnRef = pColumnRef->getChild(0);
    2184           0 :                     OTableFieldDescRef aInfo = new OTableFieldDesc();
    2185             : 
    2186           0 :                     if (    pColumnRef->count() == 3 &&
    2187           0 :                             SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") &&
    2188           0 :                             SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
    2189             :                         )
    2190           0 :                         pColumnRef = pColumnRef->getChild(1);
    2191             : 
    2192           0 :                     if (SQL_ISRULE(pColumnRef,column_ref))
    2193             :                     {
    2194           0 :                         InsertColumnRef(_pView,pColumnRef,aColumnName,aColumnAlias,aTableRange,aInfo,pTabList);
    2195           0 :                         eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
    2196           0 :                         bFirstField = sal_False;
    2197             :                     }
    2198           0 :                     else if(SQL_ISRULEOR3(pColumnRef, general_set_fct, set_fct_spec, position_exp)  ||
    2199           0 :                               SQL_ISRULEOR3(pColumnRef, extract_exp, fold, char_substring_fct)      ||
    2200           0 :                               SQL_ISRULEOR2(pColumnRef,length_exp,char_value_fct))
    2201             :                     {
    2202           0 :                         ::rtl::OUString aColumns;
    2203             :                         pColumnRef->parseNodeToPredicateStr(aColumns,
    2204             :                                                             xConnection,
    2205             :                                                             rController.getNumberFormatter(),
    2206             :                                                             _pView->getLocale(),
    2207           0 :                                                             static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
    2208           0 :                                                             &rController.getParser().getContext());
    2209             : 
    2210           0 :                         sal_Int32 nFunctionType = FKT_NONE;
    2211           0 :                         ::connectivity::OSQLParseNode* pParamRef = NULL;
    2212           0 :                         sal_Int32 nColumnRefPos = pColumnRef->count() - 2;
    2213           0 :                         if ( nColumnRefPos >= 0 && static_cast<sal_uInt32>(nColumnRefPos) < pColumnRef->count() )
    2214           0 :                             pParamRef = pColumnRef->getChild(nColumnRefPos);
    2215             : 
    2216           0 :                         if (    SQL_ISRULE(pColumnRef,general_set_fct)
    2217           0 :                             &&  SQL_ISRULE(pParamRef,column_ref) )
    2218             :                         {
    2219             :                             // Parameter auf Columnref pr"ufen
    2220           0 :                             InsertColumnRef(_pView,pParamRef,aColumnName,aColumnAlias,aTableRange,aInfo,pTabList);
    2221             :                         }
    2222           0 :                         else if ( SQL_ISRULE(pColumnRef,general_set_fct) )
    2223             :                         {
    2224           0 :                             if ( pParamRef && pParamRef->getTokenValue().toChar() == '*' )
    2225             :                             {
    2226           0 :                                 OJoinTableView::OTableWindowMap::iterator             aIter = pTabList->begin();
    2227           0 :                                 const OJoinTableView::OTableWindowMap::const_iterator aEnd  = pTabList->end();
    2228           0 :                                 for(;aIter != aEnd;++aIter)
    2229             :                                 {
    2230           0 :                                     OQueryTableWindow* pTabWin = static_cast<OQueryTableWindow*>(aIter->second);
    2231           0 :                                     if (pTabWin->ExistsField( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), aInfo ))
    2232             :                                     {
    2233           0 :                                         aInfo->SetAlias(String());
    2234           0 :                                         aInfo->SetTable(String());
    2235           0 :                                         break;
    2236             :                                     }
    2237             :                                 }
    2238             :                             }
    2239             :                             else
    2240             :                             {
    2241           0 :                                 ::rtl::OUString sFieldName = aColumns;
    2242           0 :                                 if ( pParamRef )
    2243             :                                 {   // we got an aggregate function but without column name inside
    2244             :                                     // so we set the whole argument of the function as field name
    2245           0 :                                     nFunctionType |= FKT_NUMERIC;
    2246           0 :                                     sFieldName = ::rtl::OUString();
    2247             :                                     pParamRef->parseNodeToStr(  sFieldName,
    2248             :                                                         xConnection,
    2249           0 :                                                         &rController.getParser().getContext(),
    2250             :                                                         sal_True,
    2251           0 :                                                         sal_True); // quote is to true because we need quoted elements inside the function
    2252             :                                 }
    2253           0 :                                 aInfo->SetDataType(DataType::DOUBLE);
    2254           0 :                                 aInfo->SetFieldType(TAB_NORMAL_FIELD);
    2255           0 :                                 aInfo->SetField(sFieldName);
    2256             :                             }
    2257           0 :                             aInfo->SetTabWindow(NULL);
    2258           0 :                             aInfo->SetFieldAlias(aColumnAlias);
    2259             :                         }
    2260             :                         else
    2261             :                         {
    2262           0 :                             _pView->fillFunctionInfo(pColumnRef,aColumns,aInfo);
    2263           0 :                             aInfo->SetFieldAlias(aColumnAlias);
    2264             :                         }
    2265             : 
    2266           0 :                         if ( SQL_ISRULE(pColumnRef,general_set_fct) )
    2267             :                         {
    2268           0 :                             aInfo->SetFunctionType(nFunctionType|FKT_AGGREGATE);
    2269           0 :                             String aCol(aColumns);
    2270           0 :                             aInfo->SetFunction(comphelper::string::stripEnd(aCol.GetToken(0,'('), ' '));
    2271             :                         }
    2272             :                         else
    2273           0 :                             aInfo->SetFunctionType(nFunctionType|FKT_OTHER);
    2274             : 
    2275           0 :                         eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
    2276           0 :                         bFirstField = sal_False;
    2277             :                     }
    2278             :                     else
    2279             :                     {
    2280           0 :                         ::rtl::OUString aColumns;
    2281             :                         pColumnRef->parseNodeToStr( aColumns,
    2282             :                                                     xConnection,
    2283           0 :                                                     &rController.getParser().getContext(),
    2284             :                                                     sal_True,
    2285           0 :                                                     sal_True); // quote is to true because we need quoted elements inside the function
    2286             : 
    2287           0 :                         aInfo->SetTabWindow( NULL );
    2288             : 
    2289             :                         // since we support queries in queries, the thingie might belong to an existing "table"
    2290           0 :                         OQueryTableWindow* pExistingTable = lcl_findColumnInTables( aColumns, *pTabList, aInfo );
    2291           0 :                         if ( pExistingTable )
    2292             :                         {
    2293           0 :                             aInfo->SetTabWindow( pExistingTable );
    2294           0 :                             aInfo->SetTable( pExistingTable->GetTableName() );
    2295           0 :                             aInfo->SetAlias( pExistingTable->GetAliasName() );
    2296             :                         }
    2297             : 
    2298           0 :                         aInfo->SetDataType(DataType::DOUBLE);
    2299           0 :                         aInfo->SetFieldType(TAB_NORMAL_FIELD);
    2300           0 :                         aInfo->SetField(aColumns);
    2301           0 :                         aInfo->SetFieldAlias(aColumnAlias);
    2302           0 :                         aInfo->SetFunctionType(FKT_NUMERIC | FKT_OTHER);
    2303             : 
    2304           0 :                         eErrorCode = _pView->InsertField(aInfo, sal_True, bFirstField);
    2305           0 :                         bFirstField = sal_False;
    2306             :                     }
    2307             : 
    2308           0 :                     break;
    2309             :                 }
    2310             : 
    2311             :                 OSL_FAIL( "InstallFields: don't know how to interpret this parse node!" );
    2312             : 
    2313             :                 } while ( false );
    2314           0 :             }
    2315             :         }
    2316             :         else
    2317           0 :             eErrorCode = eStatementTooComplex;
    2318             : 
    2319           0 :         return eErrorCode;
    2320             :     }
    2321             :     //------------------------------------------------------------------------------
    2322           0 :     SqlParseError GetOrderCriteria( OQueryDesignView* _pView,
    2323             :                             OSelectionBrowseBox* _pSelectionBrw,
    2324             :                             const ::connectivity::OSQLParseNode* pParseRoot )
    2325             :     {
    2326           0 :         SqlParseError eErrorCode = eOk;
    2327           0 :         if (!pParseRoot->getChild(3)->getChild(ORDER_BY_CHILD_POS)->isLeaf())
    2328             :         {
    2329           0 :             ::connectivity::OSQLParseNode* pNode = pParseRoot->getChild(3)->getChild(ORDER_BY_CHILD_POS)->getChild(2);
    2330           0 :             ::connectivity::OSQLParseNode* pParamRef = NULL;
    2331             : 
    2332           0 :             OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
    2333             :             EOrderDir eOrderDir;
    2334           0 :             for( sal_uInt32 i=0 ; i<pNode->count() ; i++ )
    2335             :             {
    2336           0 :                 OTableFieldDescRef aDragLeft = new OTableFieldDesc();
    2337           0 :                 eOrderDir = ORDER_ASC;
    2338           0 :                 ::connectivity::OSQLParseNode*  pChild = pNode->getChild( i );
    2339             : 
    2340           0 :                 if (SQL_ISTOKEN( pChild->getChild(1), DESC ) )
    2341           0 :                     eOrderDir = ORDER_DESC;
    2342             : 
    2343           0 :                 ::connectivity::OSQLParseNode* pArgument = pChild->getChild(0);
    2344             : 
    2345           0 :                 if(SQL_ISRULE(pArgument,column_ref))
    2346             :                 {
    2347           0 :                     if( eOk == FillDragInfo(_pView,pArgument,aDragLeft))
    2348           0 :                         _pSelectionBrw->AddOrder( aDragLeft, eOrderDir, i);
    2349             :                     else // it could be a alias name for a field
    2350             :                     {
    2351           0 :                         ::rtl::OUString aTableRange,aColumnName;
    2352           0 :                         ::connectivity::OSQLParseTreeIterator& rParseIter = rController.getParseIterator();
    2353           0 :                         rParseIter.getColumnRange( pArgument, aColumnName, aTableRange );
    2354             : 
    2355           0 :                         OTableFields& aList = rController.getTableFieldDesc();
    2356           0 :                         OTableFields::iterator aIter = aList.begin();
    2357           0 :                         OTableFields::iterator aEnd = aList.end();
    2358           0 :                         for(;aIter != aEnd;++aIter)
    2359             :                         {
    2360           0 :                             OTableFieldDescRef pEntry = *aIter;
    2361           0 :                             if(pEntry.is() && pEntry->GetFieldAlias() == aColumnName)
    2362           0 :                                 pEntry->SetOrderDir( eOrderDir );
    2363           0 :                         }
    2364             :                     }
    2365             :                 }
    2366           0 :                 else if(SQL_ISRULE(pArgument, general_set_fct ) &&
    2367           0 :                         SQL_ISRULE(pParamRef = pArgument->getChild(pArgument->count()-2),column_ref) &&
    2368           0 :                         eOk == FillDragInfo(_pView,pParamRef,aDragLeft))
    2369           0 :                     _pSelectionBrw->AddOrder( aDragLeft, eOrderDir, i );
    2370           0 :                 else if( SQL_ISRULE(pArgument, set_fct_spec ) )
    2371             :                 {
    2372             : 
    2373           0 :                     Reference< XConnection> xConnection = rController.getConnection();
    2374           0 :                     if(xConnection.is())
    2375             :                     {
    2376           0 :                         ::rtl::OUString sCondition;
    2377             :                         pArgument->parseNodeToPredicateStr(sCondition,
    2378             :                                                             xConnection,
    2379             :                                                             rController.getNumberFormatter(),
    2380             :                                                             _pView->getLocale(),
    2381           0 :                                                             static_cast<sal_Char>(_pView->getDecimalSeparator().toChar()),
    2382           0 :                                                             &rController.getParser().getContext());
    2383           0 :                         _pView->fillFunctionInfo(pArgument,sCondition,aDragLeft);
    2384           0 :                         aDragLeft->SetFunctionType(FKT_OTHER);
    2385           0 :                         aDragLeft->SetOrderDir(eOrderDir);
    2386           0 :                         aDragLeft->SetVisible(sal_False);
    2387           0 :                         _pSelectionBrw->AddOrder( aDragLeft, eOrderDir, i );
    2388             :                     }
    2389             :                     else
    2390           0 :                         eErrorCode = eColumnNotFound;
    2391             :                 }
    2392             :                 else
    2393           0 :                     eErrorCode = eColumnNotFound;
    2394           0 :             }
    2395             :         }
    2396           0 :         return eErrorCode;
    2397             :     }
    2398             :     //------------------------------------------------------------------------------
    2399           0 :     SqlParseError GetHavingCriteria(    OQueryDesignView* _pView,
    2400             :                             OSelectionBrowseBox* _pSelectionBrw,
    2401             :                             const ::connectivity::OSQLParseNode* pSelectRoot,
    2402             :                             sal_uInt16& rLevel )
    2403             :     {
    2404           0 :         SqlParseError eErrorCode = eOk;
    2405           0 :         if (!pSelectRoot->getChild(3)->getChild(3)->isLeaf())
    2406           0 :             eErrorCode = GetORCriteria(_pView,_pSelectionBrw,pSelectRoot->getChild(3)->getChild(3)->getChild(1),rLevel, sal_True);
    2407           0 :         return eErrorCode;
    2408             :     }
    2409             :     //------------------------------------------------------------------------------
    2410           0 :     SqlParseError GetGroupCriteria( OQueryDesignView* _pView,
    2411             :                             OSelectionBrowseBox* _pSelectionBrw,
    2412             :                             const ::connectivity::OSQLParseNode* pSelectRoot )
    2413             :     {
    2414           0 :         SqlParseError eErrorCode = eOk;
    2415           0 :         if (!pSelectRoot->getChild(3)->getChild(2)->isLeaf()) // opt_group_by_clause
    2416             :         {
    2417           0 :             OQueryController& rController = static_cast<OQueryController&>(_pView->getController());
    2418           0 :             ::connectivity::OSQLParseNode* pGroupBy = pSelectRoot->getChild(3)->getChild(2)->getChild(2);
    2419             : 
    2420           0 :             for( sal_uInt32 i=0 ; i < pGroupBy->count() && eOk == eErrorCode; ++i )
    2421             :             {
    2422           0 :                 OTableFieldDescRef aDragInfo = new OTableFieldDesc();
    2423           0 :                 ::connectivity::OSQLParseNode* pParamRef = NULL;
    2424           0 :                 ::connectivity::OSQLParseNode* pArgument = pGroupBy->getChild( i );
    2425           0 :                 if(SQL_ISRULE(pArgument,column_ref))
    2426             :                 {
    2427           0 :                     if ( eOk == (eErrorCode = FillDragInfo(_pView,pArgument,aDragInfo)) )
    2428             :                     {
    2429           0 :                         aDragInfo->SetGroupBy(sal_True);
    2430           0 :                         _pSelectionBrw->AddGroupBy(aDragInfo,i);
    2431             :                     }
    2432             :                 }
    2433           0 :                 else if(SQL_ISRULE(pArgument, general_set_fct ) &&
    2434           0 :                         SQL_ISRULE(pParamRef = pArgument->getChild(pArgument->count()-2),column_ref) &&
    2435           0 :                         eOk == FillDragInfo(_pView,pParamRef,aDragInfo))
    2436             :                 {
    2437           0 :                     aDragInfo->SetGroupBy(sal_True);
    2438           0 :                     _pSelectionBrw->AddGroupBy( aDragInfo, i );
    2439             :                 }
    2440           0 :                 else if( SQL_ISRULE(pArgument, set_fct_spec ) )
    2441             :                 {
    2442           0 :                     Reference< XConnection> xConnection = rController.getConnection();
    2443           0 :                     if(xConnection.is())
    2444             :                     {
    2445           0 :                         ::rtl::OUString sGroupByExpression;
    2446             :                         pArgument->parseNodeToStr(  sGroupByExpression,
    2447             :                                                     xConnection,
    2448           0 :                                                     &rController.getParser().getContext(),
    2449             :                                                     sal_True,
    2450           0 :                                                     sal_True); // quote is to true because we need quoted elements inside the function
    2451           0 :                         _pView->fillFunctionInfo(pArgument,sGroupByExpression,aDragInfo);
    2452           0 :                         aDragInfo->SetFunctionType(FKT_OTHER);
    2453           0 :                         aDragInfo->SetGroupBy(sal_True);
    2454           0 :                         aDragInfo->SetVisible(sal_False);
    2455           0 :                         _pSelectionBrw->AddGroupBy( aDragInfo, i );
    2456             :                     }
    2457             :                     else
    2458           0 :                         eErrorCode = eColumnNotFound;
    2459             :                 }
    2460           0 :             }
    2461             :         }
    2462           0 :         return eErrorCode;
    2463             :     }
    2464             : 
    2465             :     //------------------------------------------------------------------------------
    2466           0 :     String getParseErrorMessage( SqlParseError _eErrorCode )
    2467             :     {
    2468             :         sal_uInt16 nResId;
    2469           0 :         switch(_eErrorCode)
    2470             :         {
    2471             :             case eIllegalJoin:
    2472           0 :                 nResId = STR_QRY_ILLEGAL_JOIN;
    2473           0 :                 break;
    2474             :             case eStatementTooLong:
    2475           0 :                 nResId = STR_QRY_TOO_LONG_STATEMENT;
    2476           0 :                 break;
    2477             :             case eNoConnection:
    2478           0 :                 nResId = STR_QRY_SYNTAX;
    2479           0 :                 break;
    2480             :             case eNoSelectStatement:
    2481           0 :                 nResId = STR_QRY_NOSELECT;
    2482           0 :                 break;
    2483             :             case eColumnInLikeNotFound:
    2484           0 :                 nResId = STR_QRY_SYNTAX;
    2485           0 :                 break;
    2486             :             case eNoColumnInLike:
    2487           0 :                 nResId = STR_QRY_SYNTAX;
    2488           0 :                 break;
    2489             :             case eColumnNotFound:
    2490           0 :                 nResId = STR_QRY_SYNTAX;
    2491           0 :                 break;
    2492             :             case eNativeMode:
    2493           0 :                 nResId = STR_QRY_NATIVE;
    2494           0 :                 break;
    2495             :             case eTooManyTables:
    2496           0 :                 nResId = STR_QRY_TOO_MANY_TABLES;
    2497           0 :                 break;
    2498             :             case eTooManyConditions:
    2499           0 :                 nResId = STR_QRY_TOOMANYCOND;
    2500           0 :                 break;
    2501             :             case eTooManyColumns:
    2502           0 :                 nResId = STR_QRY_TOO_MANY_COLUMNS;
    2503           0 :                 break;
    2504             :             case eStatementTooComplex:
    2505           0 :                 nResId = STR_QRY_TOOCOMPLEX;
    2506           0 :                 break;
    2507             :             default:
    2508           0 :                 nResId = STR_QRY_SYNTAX;
    2509           0 :                 break;
    2510             :         }
    2511             :         ;
    2512           0 :         return String( ModuleRes( nResId ) );
    2513             :     }
    2514             : 
    2515             :     //------------------------------------------------------------------------------
    2516             :     //------------------------------------------------------------------------------
    2517             : }
    2518             : // end of anonymouse namespace
    2519             : DBG_NAME(OQueryDesignView)
    2520             : 
    2521           0 : OQueryDesignView::OQueryDesignView( OQueryContainerWindow* _pParent,
    2522             :                                     OQueryController& _rController,
    2523             :                                     const Reference< XMultiServiceFactory >& _rFactory)
    2524             :     :OQueryView( _pParent, _rController, _rFactory )
    2525             :     ,m_aSplitter( this )
    2526             :     ,m_eChildFocus(NONE)
    2527           0 :     ,m_bInSplitHandler( sal_False )
    2528             : {
    2529             :     DBG_CTOR(OQueryDesignView,NULL);
    2530             : 
    2531             :     try
    2532             :     {
    2533           0 :         SvtSysLocale aSysLocale;
    2534           0 :         m_aLocale = aSysLocale.GetLanguageTag().getLocale();
    2535           0 :         m_sDecimalSep = aSysLocale.GetLocaleData().getNumDecimalSep();
    2536             :     }
    2537           0 :     catch(Exception&)
    2538             :     {
    2539             :     }
    2540             : 
    2541           0 :     m_pSelectionBox = new OSelectionBrowseBox(this);
    2542             : 
    2543           0 :     setNoneVisbleRow(static_cast<OQueryController&>(getController()).getVisibleRows());
    2544           0 :     m_pSelectionBox->Show();
    2545             :     // Splitter einrichten
    2546           0 :     m_aSplitter.SetSplitHdl(LINK(this, OQueryDesignView,SplitHdl));
    2547           0 :     m_aSplitter.Show();
    2548             : 
    2549           0 : }
    2550             : // -----------------------------------------------------------------------------
    2551           0 : OQueryDesignView::~OQueryDesignView()
    2552             : {
    2553           0 :     if ( m_pTableView )
    2554           0 :         ::dbaui::notifySystemWindow(this,m_pTableView,::comphelper::mem_fun(&TaskPaneList::RemoveWindow));
    2555             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2556           0 :     ::std::auto_ptr<Window> aTemp(m_pSelectionBox);
    2557             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2558           0 :     m_pSelectionBox = NULL;
    2559             : 
    2560           0 :     DBG_DTOR(OQueryDesignView,NULL);
    2561           0 : }
    2562             : //------------------------------------------------------------------------------
    2563           0 : IMPL_LINK( OQueryDesignView, SplitHdl, void*, /*p*/ )
    2564             : {
    2565           0 :     if (!getController().isReadOnly())
    2566             :     {
    2567           0 :         m_bInSplitHandler = sal_True;
    2568           0 :         m_aSplitter.SetPosPixel( Point( m_aSplitter.GetPosPixel().X(),m_aSplitter.GetSplitPosPixel() ) );
    2569           0 :         static_cast<OQueryController&>(getController()).setSplitPos(m_aSplitter.GetSplitPosPixel());
    2570           0 :         static_cast<OQueryController&>(getController()).setModified( sal_True );
    2571           0 :         Resize();
    2572           0 :         m_bInSplitHandler = sal_True;
    2573             :     }
    2574           0 :     return 0L;
    2575             : }
    2576             : // -------------------------------------------------------------------------
    2577           0 : void OQueryDesignView::Construct()
    2578             : {
    2579           0 :     m_pTableView = new OQueryTableView(m_pScrollWindow,this);
    2580           0 :     ::dbaui::notifySystemWindow(this,m_pTableView,::comphelper::mem_fun(&TaskPaneList::AddWindow));
    2581           0 :     OQueryView::Construct();
    2582           0 : }
    2583             : // -----------------------------------------------------------------------------
    2584           0 : void OQueryDesignView::initialize()
    2585             : {
    2586           0 :     if(static_cast<OQueryController&>(getController()).getSplitPos() != -1)
    2587             :     {
    2588           0 :         m_aSplitter.SetPosPixel( Point( m_aSplitter.GetPosPixel().X(),static_cast<OQueryController&>(getController()).getSplitPos() ) );
    2589           0 :         m_aSplitter.SetSplitPosPixel(static_cast<OQueryController&>(getController()).getSplitPos());
    2590             :     }
    2591           0 :     m_pSelectionBox->initialize();
    2592           0 :     reset();
    2593           0 : }
    2594             : // -------------------------------------------------------------------------
    2595           0 : void OQueryDesignView::resizeDocumentView(Rectangle& _rPlayground)
    2596             : {
    2597           0 :     Point aPlaygroundPos( _rPlayground.TopLeft() );
    2598           0 :     Size aPlaygroundSize( _rPlayground.GetSize() );
    2599             : 
    2600             :     // calc the split pos, and forward it to the controller
    2601           0 :     sal_Int32 nSplitPos = static_cast<OQueryController&>(getController()).getSplitPos();
    2602           0 :     if ( 0 != aPlaygroundSize.Height() )
    2603             :     {
    2604           0 :         if  (   ( -1 == nSplitPos )
    2605           0 :             ||  ( nSplitPos >= aPlaygroundSize.Height() )
    2606             :             )
    2607             :         {
    2608             :             // let the selection browse box determine an optimal size
    2609           0 :             Size aSelectionBoxSize = m_pSelectionBox->CalcOptimalSize( aPlaygroundSize );
    2610           0 :             nSplitPos = aPlaygroundSize.Height() - aSelectionBoxSize.Height() - m_aSplitter.GetSizePixel().Height();
    2611             :             // still an invalid size?
    2612           0 :             if ( nSplitPos == -1 || nSplitPos >= aPlaygroundSize.Height() )
    2613           0 :                 nSplitPos = sal_Int32(aPlaygroundSize.Height()*0.6);
    2614             : 
    2615           0 :             static_cast<OQueryController&>(getController()).setSplitPos(nSplitPos);
    2616             :         }
    2617             : 
    2618           0 :         if ( !m_bInSplitHandler )
    2619             :         {   // the resize is triggered by something else than the split handler
    2620             :             // our main focus is to try to preserve the size of the selectionbrowse box
    2621           0 :             Size aSelBoxSize = m_pSelectionBox->GetSizePixel();
    2622           0 :             if ( aSelBoxSize.Height() )
    2623             :             {
    2624             :                 // keep the size of the sel box constant
    2625           0 :                 nSplitPos = aPlaygroundSize.Height() - m_aSplitter.GetSizePixel().Height() - aSelBoxSize.Height();
    2626             : 
    2627             :                 // and if the box is smaller than the optimal size, try to do something about it
    2628           0 :                 Size aSelBoxOptSize = m_pSelectionBox->CalcOptimalSize( aPlaygroundSize );
    2629           0 :                 if ( aSelBoxOptSize.Height() > aSelBoxSize.Height() )
    2630             :                 {
    2631           0 :                     nSplitPos = aPlaygroundSize.Height() - m_aSplitter.GetSizePixel().Height() - aSelBoxOptSize.Height();
    2632             :                 }
    2633             : 
    2634           0 :                 static_cast< OQueryController& >(getController()).setSplitPos( nSplitPos );
    2635             :             }
    2636             :         }
    2637             :     }
    2638             : 
    2639             :     // normalize the split pos
    2640           0 :     Point   aSplitPos       = Point( _rPlayground.Left(), nSplitPos );
    2641           0 :     Size    aSplitSize      = Size( _rPlayground.GetSize().Width(), m_aSplitter.GetSizePixel().Height() );
    2642             : 
    2643           0 :     if( ( aSplitPos.Y() + aSplitSize.Height() ) > ( aPlaygroundSize.Height() ))
    2644           0 :         aSplitPos.Y() = aPlaygroundSize.Height() - aSplitSize.Height();
    2645             : 
    2646           0 :     if( aSplitPos.Y() <= aPlaygroundPos.Y() )
    2647           0 :         aSplitPos.Y() = aPlaygroundPos.Y() + sal_Int32(aPlaygroundSize.Height() * 0.2);
    2648             : 
    2649             :     // position the table
    2650           0 :     Size aTableViewSize(aPlaygroundSize.Width(), aSplitPos.Y() - aPlaygroundPos.Y());
    2651           0 :     m_pScrollWindow->SetPosSizePixel(aPlaygroundPos, aTableViewSize);
    2652             : 
    2653             :     // position the selection browse box
    2654           0 :     Point aPos( aPlaygroundPos.X(), aSplitPos.Y() + aSplitSize.Height() );
    2655           0 :     m_pSelectionBox->SetPosSizePixel( aPos, Size( aPlaygroundSize.Width(), aPlaygroundSize.Height() - aSplitSize.Height() - aTableViewSize.Height() ));
    2656             : 
    2657             :     // set the size of the splitter
    2658           0 :     m_aSplitter.SetPosSizePixel( aSplitPos, aSplitSize );
    2659           0 :     m_aSplitter.SetDragRectPixel( _rPlayground );
    2660             : 
    2661             :     // just for completeness: there is no space left, we occupied it all ...
    2662           0 :     _rPlayground.SetPos( _rPlayground.BottomRight() );
    2663           0 :     _rPlayground.SetSize( Size( 0, 0 ) );
    2664           0 : }
    2665             : // -----------------------------------------------------------------------------
    2666           0 : void OQueryDesignView::setReadOnly(sal_Bool _bReadOnly)
    2667             : {
    2668           0 :     m_pSelectionBox->SetReadOnly(_bReadOnly);
    2669           0 : }
    2670             : // -----------------------------------------------------------------------------
    2671           0 : void OQueryDesignView::clear()
    2672             : {
    2673           0 :     m_pSelectionBox->ClearAll(); // clear the whole selection
    2674           0 :     m_pTableView->ClearAll();
    2675           0 : }
    2676             : // -----------------------------------------------------------------------------
    2677           0 : void OQueryDesignView::setStatement(const ::rtl::OUString& /*_rsStatement*/)
    2678             : {
    2679           0 : }
    2680             : // -----------------------------------------------------------------------------
    2681           0 : void OQueryDesignView::copy()
    2682             : {
    2683           0 :     if( m_eChildFocus == SELECTION)
    2684           0 :         m_pSelectionBox->copy();
    2685           0 : }
    2686             : // -----------------------------------------------------------------------------
    2687           0 : sal_Bool OQueryDesignView::isCutAllowed()
    2688             : {
    2689           0 :     sal_Bool bAllowed = sal_False;
    2690           0 :     if ( SELECTION == m_eChildFocus )
    2691           0 :         bAllowed = m_pSelectionBox->isCutAllowed();
    2692           0 :     return bAllowed;
    2693             : }
    2694             : // -----------------------------------------------------------------------------
    2695           0 : sal_Bool OQueryDesignView::isPasteAllowed()
    2696             : {
    2697           0 :     sal_Bool bAllowed = sal_False;
    2698           0 :     if ( SELECTION == m_eChildFocus )
    2699           0 :         bAllowed = m_pSelectionBox->isPasteAllowed();
    2700           0 :     return bAllowed;
    2701             : }
    2702             : // -----------------------------------------------------------------------------
    2703           0 : sal_Bool OQueryDesignView::isCopyAllowed()
    2704             : {
    2705           0 :     sal_Bool bAllowed = sal_False;
    2706           0 :     if ( SELECTION == m_eChildFocus )
    2707           0 :         bAllowed = m_pSelectionBox->isCopyAllowed();
    2708           0 :     return bAllowed;
    2709             : }
    2710             : // -----------------------------------------------------------------------------
    2711           0 : void OQueryDesignView::stopTimer()
    2712             : {
    2713           0 :     m_pSelectionBox->stopTimer();
    2714           0 : }
    2715             : // -----------------------------------------------------------------------------
    2716           0 : void OQueryDesignView::startTimer()
    2717             : {
    2718           0 :     m_pSelectionBox->startTimer();
    2719           0 : }
    2720             : // -----------------------------------------------------------------------------
    2721           0 : void OQueryDesignView::cut()
    2722             : {
    2723           0 :     if( m_eChildFocus == SELECTION)
    2724             :     {
    2725           0 :         m_pSelectionBox->cut();
    2726           0 :         static_cast<OQueryController&>(getController()).setModified(sal_True);
    2727             :     }
    2728           0 : }
    2729             : // -----------------------------------------------------------------------------
    2730           0 : void OQueryDesignView::paste()
    2731             : {
    2732           0 :     if( m_eChildFocus == SELECTION)
    2733             :     {
    2734           0 :         m_pSelectionBox->paste();
    2735           0 :         static_cast<OQueryController&>(getController()).setModified(sal_True);
    2736             :     }
    2737           0 : }
    2738             : // -----------------------------------------------------------------------------
    2739           0 : void OQueryDesignView::TableDeleted(const ::rtl::OUString& rAliasName)
    2740             : {
    2741             :     // Nachricht, dass Tabelle aus dem Fenster gel"oscht wurde
    2742           0 :     DeleteFields(rAliasName);
    2743           0 :     static_cast<OQueryController&>(getController()).InvalidateFeature(ID_BROWSER_ADDTABLE); // view nochmal bescheid sagen
    2744           0 : }
    2745             : //------------------------------------------------------------------------------
    2746           0 : void OQueryDesignView::DeleteFields( const ::rtl::OUString& rAliasName )
    2747             : {
    2748           0 :     m_pSelectionBox->DeleteFields( rAliasName );
    2749           0 : }
    2750             : // -----------------------------------------------------------------------------
    2751           0 : bool OQueryDesignView::HasFieldByAliasName(const ::rtl::OUString& rFieldName, OTableFieldDescRef& rInfo)  const
    2752             : {
    2753           0 :     return m_pSelectionBox->HasFieldByAliasName( rFieldName, rInfo);
    2754             : }
    2755             : // -----------------------------------------------------------------------------
    2756           0 : SqlParseError OQueryDesignView::InsertField( const OTableFieldDescRef& rInfo, sal_Bool bVis, sal_Bool bActivate)
    2757             : {
    2758           0 :     return m_pSelectionBox->InsertField( rInfo, BROWSER_INVALIDID,bVis, bActivate ).is() ? eOk : eTooManyColumns;
    2759             : }
    2760             : // -----------------------------------------------------------------------------
    2761           0 : sal_Int32 OQueryDesignView::getColWidth(sal_uInt16 _nColPos) const
    2762             : {
    2763           0 :     static sal_Int32 s_nDefaultWidth = GetTextWidth(String(RTL_CONSTASCII_USTRINGPARAM("0"))) * 15;
    2764           0 :     sal_Int32 nWidth = static_cast<OQueryController&>(getController()).getColWidth(_nColPos);
    2765           0 :     if ( !nWidth )
    2766           0 :         nWidth = s_nDefaultWidth;
    2767           0 :     return nWidth;
    2768             : }
    2769             : //------------------------------------------------------------------------------
    2770           0 : void OQueryDesignView::fillValidFields(const ::rtl::OUString& sAliasName, ComboBox* pFieldList)
    2771             : {
    2772             :     OSL_ENSURE(pFieldList != NULL, "OQueryDesignView::FillValidFields : What the hell do you think I can do with a NULL-ptr ? This will crash !");
    2773           0 :     pFieldList->Clear();
    2774             : 
    2775           0 :     sal_Bool bAllTables = sAliasName.isEmpty();
    2776             : 
    2777           0 :     OJoinTableView::OTableWindowMap* pTabWins = m_pTableView->GetTabWinMap();
    2778           0 :     ::rtl::OUString strCurrentPrefix;
    2779           0 :     ::std::vector< ::rtl::OUString> aFields;
    2780           0 :     OJoinTableView::OTableWindowMap::iterator aIter = pTabWins->begin();
    2781           0 :     OJoinTableView::OTableWindowMap::iterator aEnd  = pTabWins->end();
    2782           0 :     for(;aIter != aEnd;++aIter)
    2783             :     {
    2784           0 :         OQueryTableWindow* pCurrentWin = static_cast<OQueryTableWindow*>(aIter->second);
    2785           0 :         if (bAllTables || (pCurrentWin->GetAliasName() == sAliasName))
    2786             :         {
    2787           0 :             strCurrentPrefix = pCurrentWin->GetAliasName();
    2788           0 :             strCurrentPrefix += ::rtl::OUString('.');
    2789             : 
    2790           0 :             pCurrentWin->EnumValidFields(aFields);
    2791             : 
    2792           0 :             ::std::vector< ::rtl::OUString>::iterator aStrIter = aFields.begin();
    2793           0 :             ::std::vector< ::rtl::OUString>::iterator aStrEnd = aFields.end();
    2794           0 :             for(;aStrIter != aStrEnd;++aStrIter)
    2795             :             {
    2796           0 :                 if (bAllTables || aStrIter->toChar() == '*')
    2797           0 :                     pFieldList->InsertEntry(::rtl::OUString(strCurrentPrefix) += *aStrIter);
    2798             :                 else
    2799           0 :                     pFieldList->InsertEntry(*aStrIter);
    2800             :             }
    2801             : 
    2802           0 :             if (!bAllTables)
    2803             :                 // das heisst, dass ich in diesen Block kam, weil der Tabellenname genau der gesuchte war, also bin ich fertig
    2804             :                 // (dadurch verhindere ich auch das doppelte Einfuegen von Feldern, wenn eine Tabelle mehrmals als TabWin vorkommt)
    2805             :                 break;
    2806             :         }
    2807           0 :     }
    2808           0 : }
    2809             : // -----------------------------------------------------------------------------
    2810           0 : long OQueryDesignView::PreNotify(NotifyEvent& rNEvt)
    2811             : {
    2812           0 :     switch (rNEvt.GetType())
    2813             :     {
    2814             :         case EVENT_GETFOCUS:
    2815             : #if OSL_DEBUG_LEVEL > 0
    2816             :             {
    2817             :                 Window* pFocus = Application::GetFocusWindow();
    2818             :                 (void)pFocus;
    2819             :             }
    2820             : #endif
    2821             : 
    2822           0 :             if ( m_pSelectionBox && m_pSelectionBox->HasChildPathFocus() )
    2823           0 :                 m_eChildFocus = SELECTION;
    2824             :             else
    2825           0 :                 m_eChildFocus = TABLEVIEW;
    2826           0 :             break;
    2827             :     }
    2828             : 
    2829           0 :     return OQueryView::PreNotify(rNEvt);
    2830             : }
    2831             : //------------------------------------------------------------------------------
    2832             : 
    2833             : 
    2834             : // -----------------------------------------------------------------------------
    2835             : // check if the statement is correct when not returning false
    2836           0 : sal_Bool OQueryDesignView::checkStatement()
    2837             : {
    2838           0 :     sal_Bool bRet = sal_True;
    2839           0 :     if ( m_pSelectionBox )
    2840           0 :         bRet = m_pSelectionBox->Save(); // an error occurred so we return no
    2841           0 :     return bRet;
    2842             : }
    2843             : //-------------------------------------------------------------------------------
    2844           0 : ::rtl::OUString OQueryDesignView::getStatement()
    2845             : {
    2846           0 :     OQueryController& rController = static_cast<OQueryController&>(getController());
    2847           0 :     m_rController.clearError();
    2848             :     // used for fields which aren't any longer in the statement
    2849           0 :     OTableFields& rUnUsedFields = rController.getUnUsedFields();
    2850           0 :     OTableFields().swap( rUnUsedFields );
    2851             : 
    2852             :     // create the select columns
    2853           0 :     sal_uInt32 nFieldcount = 0;
    2854           0 :     OTableFields& rFieldList = rController.getTableFieldDesc();
    2855           0 :     OTableFields::iterator aIter = rFieldList.begin();
    2856           0 :     OTableFields::iterator aEnd = rFieldList.end();
    2857           0 :     for(;aIter != aEnd;++aIter)
    2858             :     {
    2859           0 :         OTableFieldDescRef pEntryField = *aIter;
    2860           0 :         if (!pEntryField->GetField().isEmpty() && pEntryField->IsVisible() )
    2861           0 :             ++nFieldcount;
    2862           0 :         else if (!pEntryField->GetField().isEmpty()            &&
    2863           0 :                 !pEntryField->HasCriteria()                 &&
    2864           0 :                 pEntryField->isNoneFunction()               &&
    2865           0 :                 pEntryField->GetOrderDir() == ORDER_NONE    &&
    2866           0 :                 !pEntryField->IsGroupBy()                   &&
    2867           0 :                 pEntryField->GetFunction().isEmpty() )
    2868           0 :             rUnUsedFields.push_back(pEntryField);
    2869           0 :     }
    2870           0 :     if ( !nFieldcount ) // keine Felder sichtbar also zur"uck
    2871             :     {
    2872           0 :         rUnUsedFields = rFieldList;
    2873           0 :         return ::rtl::OUString();
    2874             :     }
    2875             : 
    2876           0 :     OQueryTableView::OTableWindowMap* pTabList   = m_pTableView->GetTabWinMap();
    2877           0 :     sal_uInt32 nTabcount        = pTabList->size();
    2878             : 
    2879           0 :     ::rtl::OUString aFieldListStr(GenerateSelectList(this,rFieldList,nTabcount>1));
    2880           0 :     if( aFieldListStr.isEmpty() )
    2881           0 :         return ::rtl::OUString();
    2882             :     // Ausnahmebehandlung, wenn keine Felder angegeben worden sind
    2883             :     // Dann darf die Tabpage nicht gewechselt werden
    2884             :     // Im TabBarSelectHdl wird der SQL-::rtl::OUString auf STATEMENT_NOFIELDS abgefragt
    2885             :     // und eine Errormeldung erzeugt
    2886             :     // ----------------- Tabellenliste aufbauen ----------------------
    2887             : 
    2888           0 :     const ::std::vector<OTableConnection*>* pConnList = m_pTableView->getTableConnections();
    2889           0 :     Reference< XConnection> xConnection = rController.getConnection();
    2890           0 :     ::rtl::OUString aTableListStr(GenerateFromClause(xConnection,pTabList,pConnList));
    2891             :     OSL_ENSURE(!aTableListStr.isEmpty(), "OQueryDesignView::getStatement() : unerwartet : habe Felder, aber keine Tabellen !");
    2892             :     // wenn es Felder gibt, koennen die nur durch Einfuegen aus einer schon existenten Tabelle entstanden sein; wenn andererseits
    2893             :     // eine Tabelle geloescht wird, verschwinden auch die zugehoerigen Felder -> ergo KANN es das nicht geben, dass Felder
    2894             :     // existieren, aber keine Tabellen (und aFieldListStr hat schon eine Laenge, das stelle ich oben sicher)
    2895           0 :     ::rtl::OUStringBuffer aHavingStr,aCriteriaListStr;
    2896             :     // ----------------- Kriterien aufbauen ----------------------
    2897           0 :     if (!GenerateCriterias(this,aCriteriaListStr,aHavingStr,rFieldList, nTabcount > 1))
    2898           0 :         return ::rtl::OUString();
    2899             : 
    2900           0 :     ::rtl::OUString aJoinCrit;
    2901           0 :     GenerateInnerJoinCriterias(xConnection,aJoinCrit,pConnList);
    2902           0 :     if(!aJoinCrit.isEmpty())
    2903             :     {
    2904           0 :         ::rtl::OUString aTmp(RTL_CONSTASCII_USTRINGPARAM("( "));
    2905           0 :         aTmp += aJoinCrit;
    2906           0 :         aTmp += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" )"));
    2907           0 :         if(aCriteriaListStr.getLength())
    2908             :         {
    2909           0 :             aTmp += C_AND;
    2910           0 :             aTmp += aCriteriaListStr.makeStringAndClear();
    2911             :         }
    2912           0 :         aCriteriaListStr = aTmp;
    2913             :     }
    2914             :     // ----------------- Statement aufbauen ----------------------
    2915           0 :     ::rtl::OUStringBuffer aSqlCmd(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT ")));
    2916           0 :     if(static_cast<OQueryController&>(getController()).isDistinct())
    2917           0 :         aSqlCmd.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" DISTINCT ")));
    2918           0 :     aSqlCmd.append(aFieldListStr);
    2919           0 :     aSqlCmd.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM ")));
    2920           0 :     aSqlCmd.append(aTableListStr);
    2921             : 
    2922           0 :     if (aCriteriaListStr.getLength())
    2923             :     {
    2924           0 :         aSqlCmd.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE ")));
    2925           0 :         aSqlCmd.append(aCriteriaListStr.makeStringAndClear());
    2926             :     }
    2927             :     // ----------------- GroupBy aufbauen und Anh"angen ------------
    2928           0 :     Reference<XDatabaseMetaData> xMeta;
    2929           0 :     if ( xConnection.is() )
    2930           0 :         xMeta = xConnection->getMetaData();
    2931           0 :     sal_Bool bUseAlias = nTabcount > 1;
    2932           0 :     if ( xMeta.is() )
    2933           0 :         bUseAlias = bUseAlias || !xMeta->supportsGroupByUnrelated();
    2934             : 
    2935           0 :     aSqlCmd.append(GenerateGroupBy(this,rFieldList,bUseAlias));
    2936             :     // ----------------- having Anh"angen ------------
    2937           0 :     if(aHavingStr.getLength())
    2938             :     {
    2939           0 :         aSqlCmd.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" HAVING ")));
    2940           0 :         aSqlCmd.append(aHavingStr.makeStringAndClear());
    2941             :     }
    2942             :     // ----------------- Sortierung aufbauen und Anh"angen ------------
    2943           0 :     ::rtl::OUString sOrder;
    2944           0 :     SqlParseError eErrorCode = eOk;
    2945           0 :     if ( (eErrorCode = GenerateOrder(this,rFieldList,nTabcount > 1,sOrder)) == eOk)
    2946           0 :         aSqlCmd.append(sOrder);
    2947             :     else
    2948             :     {
    2949           0 :         if ( !m_rController.hasError() )
    2950           0 :             m_rController.appendError( getParseErrorMessage( eErrorCode ) );
    2951             : 
    2952           0 :         m_rController.displayError();
    2953             :     }
    2954             : 
    2955           0 :     ::rtl::OUString sSQL = aSqlCmd.makeStringAndClear();
    2956           0 :     if ( xConnection.is() )
    2957             :     {
    2958           0 :         ::connectivity::OSQLParser& rParser( rController.getParser() );
    2959           0 :         ::rtl::OUString sErrorMessage;
    2960             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2961           0 :         ::std::auto_ptr<OSQLParseNode> pParseNode( rParser.parseTree( sErrorMessage, sSQL, sal_True ) );
    2962             :         SAL_WNODEPRECATED_DECLARATIONS_POP
    2963           0 :         if ( pParseNode.get() )
    2964             :         {
    2965           0 :             OSQLParseNode* pNode = pParseNode->getChild(3)->getChild(1);
    2966           0 :             if ( pNode->count() > 1 )
    2967             :             {
    2968           0 :                 ::connectivity::OSQLParseNode * pCondition = pNode->getChild(1);
    2969           0 :                 if ( pCondition ) // no where clause
    2970             :                 {
    2971           0 :                     OSQLParseNode::compress(pCondition);
    2972           0 :                     ::rtl::OUString sTemp;
    2973           0 :                     pParseNode->parseNodeToStr(sTemp,xConnection);
    2974           0 :                     sSQL = sTemp;
    2975             :                 }
    2976             :             }
    2977           0 :         }
    2978             :     }
    2979           0 :     return sSQL;
    2980             : }
    2981             : // -----------------------------------------------------------------------------
    2982             : // -----------------------------------------------------------------------------
    2983           0 : void OQueryDesignView::setSlotEnabled(sal_Int32 _nSlotId,sal_Bool _bEnable)
    2984             : {
    2985             :     sal_uInt16 nRow;
    2986           0 :     switch (_nSlotId)
    2987             :     {
    2988             :         case SID_QUERY_VIEW_FUNCTIONS:
    2989           0 :             nRow = BROW_FUNCTION_ROW;
    2990           0 :             break;
    2991             :         case SID_QUERY_VIEW_TABLES:
    2992           0 :             nRow = BROW_TABLE_ROW;
    2993           0 :             break;
    2994             :         case SID_QUERY_VIEW_ALIASES:
    2995           0 :             nRow = BROW_COLUMNALIAS_ROW;
    2996           0 :             break;
    2997             :         default:
    2998             :             // ????????????
    2999           0 :             nRow = 0;
    3000           0 :             break;
    3001             :     }
    3002           0 :     m_pSelectionBox->SetRowVisible(nRow,_bEnable);
    3003           0 :     m_pSelectionBox->Invalidate();
    3004           0 : }
    3005             : // -----------------------------------------------------------------------------
    3006           0 : sal_Bool OQueryDesignView::isSlotEnabled(sal_Int32 _nSlotId)
    3007             : {
    3008             :     sal_uInt16 nRow;
    3009           0 :     switch (_nSlotId)
    3010             :     {
    3011             :         case SID_QUERY_VIEW_FUNCTIONS:
    3012           0 :             nRow = BROW_FUNCTION_ROW;
    3013           0 :             break;
    3014             :         case SID_QUERY_VIEW_TABLES:
    3015           0 :             nRow = BROW_TABLE_ROW;
    3016           0 :             break;
    3017             :         case SID_QUERY_VIEW_ALIASES:
    3018           0 :             nRow = BROW_COLUMNALIAS_ROW;
    3019           0 :             break;
    3020             :         default:
    3021             :             // ?????????
    3022           0 :             nRow = 0;
    3023           0 :             break;
    3024             :     }
    3025           0 :     return m_pSelectionBox->IsRowVisible(nRow);
    3026             : }
    3027             : // -----------------------------------------------------------------------------
    3028           0 : void OQueryDesignView::SaveUIConfig()
    3029             : {
    3030           0 :     OQueryController& rCtrl = static_cast<OQueryController&>(getController());
    3031           0 :     rCtrl.SaveTabWinsPosSize( m_pTableView->GetTabWinMap(), m_pScrollWindow->GetHScrollBar()->GetThumbPos(), m_pScrollWindow->GetVScrollBar()->GetThumbPos() );
    3032           0 :     rCtrl.setVisibleRows( m_pSelectionBox->GetNoneVisibleRows() );
    3033           0 :     if ( m_aSplitter.GetSplitPosPixel() != 0 )
    3034           0 :         rCtrl.setSplitPos( m_aSplitter.GetSplitPosPixel() );
    3035           0 : }
    3036             : // -----------------------------------------------------------------------------
    3037           0 : OSQLParseNode* OQueryDesignView::getPredicateTreeFromEntry(OTableFieldDescRef pEntry,
    3038             :                                                            const String& _sCriteria,
    3039             :                                                            ::rtl::OUString& _rsErrorMessage,
    3040             :                                                            Reference<XPropertySet>& _rxColumn) const
    3041             : {
    3042             :     OSL_ENSURE(pEntry.is(),"Entry is null!");
    3043           0 :     if(!pEntry.is())
    3044           0 :         return NULL;
    3045           0 :     Reference< XConnection> xConnection = static_cast<OQueryController&>(getController()).getConnection();
    3046           0 :     if(!xConnection.is())
    3047           0 :         return NULL;
    3048             : 
    3049           0 :     ::connectivity::OSQLParser& rParser( static_cast<OQueryController&>(getController()).getParser() );
    3050           0 :     OQueryTableWindow* pWin = static_cast<OQueryTableWindow*>(pEntry->GetTabWindow());
    3051             : 
    3052           0 :     String sTest(_sCriteria);
    3053             :     // special handling for functions
    3054           0 :     if ( pEntry->GetFunctionType() & (FKT_OTHER | FKT_AGGREGATE | FKT_NUMERIC) )
    3055             :     {
    3056             :         // we have a function here so we have to distinguish the type of return value
    3057           0 :         String sFunction;
    3058           0 :         if ( pEntry->isNumericOrAggreateFunction() )
    3059           0 :             sFunction = pEntry->GetFunction();
    3060             : 
    3061           0 :         if ( !sFunction.Len() )
    3062           0 :             sFunction = pEntry->GetField();
    3063             : 
    3064           0 :         if (comphelper::string::getTokenCount(sFunction, '(') > 1)
    3065           0 :             sFunction = sFunction.GetToken(0,'('); // this should be the name of the function
    3066             : 
    3067           0 :         sal_Int32 nType = ::connectivity::OSQLParser::getFunctionReturnType(sFunction,&rParser.getContext());
    3068           0 :         if ( nType == DataType::OTHER || (!sFunction.Len() && pEntry->isNumericOrAggreateFunction()) )
    3069             :         {
    3070             :             // first try the international version
    3071           0 :             ::rtl::OUString sSql;
    3072           0 :             sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT * "));
    3073           0 :             sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM x WHERE "));
    3074           0 :             sSql += pEntry->GetField();
    3075           0 :             sSql += _sCriteria;
    3076             :             SAL_WNODEPRECATED_DECLARATIONS_PUSH
    3077           0 :             ::std::auto_ptr<OSQLParseNode> pParseNode( rParser.parseTree( _rsErrorMessage, sSql, sal_True ) );
    3078             :             SAL_WNODEPRECATED_DECLARATIONS_POP
    3079           0 :             nType = DataType::DOUBLE;
    3080           0 :             if ( pParseNode.get() )
    3081             :             {
    3082           0 :                 OSQLParseNode* pColumnRef = pParseNode->getByRule(OSQLParseNode::column_ref);
    3083           0 :                 if ( pColumnRef )
    3084             :                 {
    3085           0 :                     OTableFieldDescRef aField = new OTableFieldDesc();
    3086           0 :                     if ( eOk == FillDragInfo(this,pColumnRef,aField) )
    3087             :                     {
    3088           0 :                         nType = aField->GetDataType();
    3089           0 :                     }
    3090             :                 }
    3091           0 :             }
    3092             :         }
    3093             : 
    3094           0 :         Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
    3095             :         parse::OParseColumn* pColumn = new parse::OParseColumn( pEntry->GetField(),
    3096             :                                                                 ::rtl::OUString(),
    3097             :                                                                 ::rtl::OUString(),
    3098             :                                                                 ::rtl::OUString(),
    3099             :                                                                 ColumnValue::NULLABLE_UNKNOWN,
    3100             :                                                                 0,
    3101             :                                                                 0,
    3102             :                                                                 nType,
    3103             :                                                                 sal_False,
    3104             :                                                                 sal_False,
    3105           0 :                                                                 xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers(),
    3106             :                                                                 ::rtl::OUString(),
    3107             :                                                                 ::rtl::OUString(),
    3108           0 :                                                                 ::rtl::OUString());
    3109           0 :         _rxColumn = pColumn;
    3110           0 :         pColumn->setFunction(sal_True);
    3111           0 :         pColumn->setRealName(pEntry->GetField());
    3112             :     }
    3113             :     else
    3114             :     {
    3115           0 :         if (pWin)
    3116             :         {
    3117           0 :             Reference<XNameAccess> xColumns = pWin->GetOriginalColumns();
    3118           0 :             if (xColumns.is() && xColumns->hasByName(pEntry->GetField()))
    3119           0 :                 xColumns->getByName(pEntry->GetField()) >>= _rxColumn;
    3120             :         }
    3121             :     }
    3122             : 
    3123             :     OSQLParseNode* pParseNode = rParser.predicateTree(  _rsErrorMessage,
    3124             :                                                         sTest,
    3125           0 :                                                         static_cast<OQueryController&>(getController()).getNumberFormatter(),
    3126           0 :                                                         _rxColumn);
    3127           0 :     return pParseNode;
    3128             : }
    3129             : // -----------------------------------------------------------------------------
    3130           0 : void OQueryDesignView::GetFocus()
    3131             : {
    3132           0 :     OQueryView::GetFocus();
    3133           0 :     if ( m_pSelectionBox && !m_pSelectionBox->HasChildPathFocus() )
    3134             :     {
    3135             :         // first we have to deactivate the current cell to refill when necessary
    3136           0 :         m_pSelectionBox->DeactivateCell();
    3137           0 :         m_pSelectionBox->ActivateCell(m_pSelectionBox->GetCurRow(), m_pSelectionBox->GetCurColumnId());
    3138           0 :         m_pSelectionBox->GrabFocus();
    3139             :     }
    3140           0 : }
    3141             : // -----------------------------------------------------------------------------
    3142           0 : void OQueryDesignView::reset()
    3143             : {
    3144           0 :     m_pTableView->ClearAll();
    3145           0 :     m_pTableView->ReSync();
    3146           0 : }
    3147             : // -----------------------------------------------------------------------------
    3148           0 : void OQueryDesignView::setNoneVisbleRow(sal_Int32 _nRows)
    3149             : {
    3150           0 :     m_pSelectionBox->SetNoneVisbleRow(_nRows);
    3151           0 : }
    3152             : 
    3153             : // -----------------------------------------------------------------------------
    3154           0 : void OQueryDesignView::initByFieldDescriptions( const Sequence< PropertyValue >& i_rFieldDescriptions )
    3155             : {
    3156           0 :     OQueryController& rController = static_cast< OQueryController& >( getController() );
    3157             : 
    3158           0 :     m_pSelectionBox->PreFill();
    3159           0 :     m_pSelectionBox->SetReadOnly( rController.isReadOnly() );
    3160           0 :     m_pSelectionBox->Fill();
    3161             : 
    3162           0 :     for (   const PropertyValue* field = i_rFieldDescriptions.getConstArray();
    3163           0 :             field != i_rFieldDescriptions.getConstArray() + i_rFieldDescriptions.getLength();
    3164             :             ++field
    3165             :         )
    3166             :     {
    3167           0 :         ::rtl::Reference< OTableFieldDesc > pField( new OTableFieldDesc() );
    3168           0 :         pField->Load( *field, true );
    3169           0 :         InsertField( pField, sal_True, sal_False );
    3170           0 :     }
    3171             : 
    3172           0 :     rController.ClearUndoManager();
    3173           0 :     m_pSelectionBox->Invalidate();
    3174           0 : }
    3175             : 
    3176             : // -----------------------------------------------------------------------------
    3177           0 : bool OQueryDesignView::initByParseIterator( ::dbtools::SQLExceptionInfo* _pErrorInfo )
    3178             : {
    3179           0 :     SqlParseError eErrorCode = eNativeMode;
    3180           0 :     m_rController.clearError();
    3181             : 
    3182             :     try
    3183             :     {
    3184           0 :         eErrorCode = InitFromParseNodeImpl( this, m_pSelectionBox );
    3185             : 
    3186           0 :         if ( eErrorCode != eOk )
    3187             :         {
    3188           0 :             if ( !m_rController.hasError() )
    3189           0 :                 m_rController.appendError( getParseErrorMessage( eErrorCode ) );
    3190             : 
    3191           0 :             if ( _pErrorInfo )
    3192             :             {
    3193           0 :                 *_pErrorInfo = m_rController.getError();
    3194             :             }
    3195             :             else
    3196             :             {
    3197           0 :                 m_rController.displayError();
    3198             :             }
    3199             :         }
    3200             :     }
    3201           0 :     catch ( const Exception& )
    3202             :     {
    3203             :         DBG_UNHANDLED_EXCEPTION();
    3204             :     }
    3205           0 :     return eErrorCode == eOk;
    3206             : }
    3207             : 
    3208             : // Utility function for fillFunctionInfo
    3209             : namespace {
    3210           0 :     sal_Int32 char_datatype(const::connectivity::OSQLParseNode* pDataType, const unsigned int offset) {
    3211           0 :         int cnt = pDataType->count() - offset;
    3212           0 :         if ( cnt < 0 )
    3213             :         {
    3214             :             OSL_FAIL("internal error in decoding character datatype specification");
    3215           0 :             return DataType::VARCHAR;
    3216             :         }
    3217           0 :         else if ( cnt == 0 )
    3218             :         {
    3219           0 :             if ( offset == 0 )
    3220             :             {
    3221             :                 // The datatype is the node itself
    3222           0 :                 if ( SQL_ISTOKENOR2 (pDataType, CHARACTER, CHAR) )
    3223           0 :                     return DataType::CHAR;
    3224           0 :                 else if ( SQL_ISTOKEN (pDataType, VARCHAR) )
    3225           0 :                     return DataType::VARCHAR;
    3226           0 :                 else if ( SQL_ISTOKEN (pDataType, CLOB) )
    3227           0 :                     return DataType::CLOB;
    3228             :                 else
    3229             :                 {
    3230             :                     OSL_FAIL("unknown/unexpected token in decoding character datatype specification");
    3231           0 :                     return DataType::VARCHAR;
    3232             :                 }
    3233             :             }
    3234             :             else
    3235             :             {
    3236             :                 // No child left to read!
    3237             :                 OSL_FAIL("incomplete datatype in decoding character datatype specification");
    3238           0 :                 return DataType::VARCHAR;
    3239             :             }
    3240             :         }
    3241             : 
    3242           0 :         if ( SQL_ISTOKEN(pDataType->getChild(offset), NATIONAL) )
    3243           0 :             return char_datatype(pDataType, offset+1);
    3244           0 :         else if ( SQL_ISTOKENOR3(pDataType->getChild(offset), CHARACTER, CHAR, NCHAR) )
    3245             :         {
    3246           0 :             if ( cnt > 2 && SQL_ISTOKEN(pDataType->getChild(offset+1), LARGE) && SQL_ISTOKEN(pDataType->getChild(offset+2), OBJECT) )
    3247           0 :                 return DataType::CLOB;
    3248           0 :             else if ( cnt > 1 && SQL_ISTOKEN(pDataType->getChild(offset+1), VARYING) )
    3249           0 :                 return DataType::VARCHAR;
    3250             :             else
    3251           0 :                 return DataType::CHAR;
    3252             :         }
    3253           0 :         else if ( SQL_ISTOKEN (pDataType->getChild(offset), VARCHAR) )
    3254           0 :             return DataType::VARCHAR;
    3255           0 :         else if ( SQL_ISTOKENOR2 (pDataType->getChild(offset), CLOB, NCLOB) )
    3256           0 :             return DataType::CLOB;
    3257             : 
    3258             :         OSL_FAIL("unrecognised character datatype");
    3259           0 :         return DataType::VARCHAR;
    3260             :     }
    3261             : }
    3262             : 
    3263             : //------------------------------------------------------------------------------
    3264             : // Try to guess the type of an expression in simple cases.
    3265             : // Originally meant to be called only on a function call (hence the misnomer),
    3266             : // but now tries to do the best it can also in other cases.
    3267             : // Don't completely rely on fillFunctionInfo,
    3268             : // it won't look at the function's arguments to find the return type
    3269             : // (in particular, in the case of general_set_fct,
    3270             : //  the return type is the type of the argument;
    3271             : //  if that is (as is typical) a column reference,
    3272             : //  it is the type of the column).
    3273             : // TODO: There is similar "guess the expression's type" code in several places:
    3274             : //       SelectionBrowseBox.cxx: OSelectionBrowseBox::saveField
    3275             : //       QueryDesignView.cxx: InstallFields, GetOrderCriteria, GetGroupCriteria
    3276             : //       If possible, they should be factorised into this function
    3277             : //       (which should then be renamed...)
    3278             : 
    3279           0 : void OQueryDesignView::fillFunctionInfo(  const ::connectivity::OSQLParseNode* pNode
    3280             :                                         ,const ::rtl::OUString& sFunctionTerm
    3281             :                                         ,OTableFieldDescRef& aInfo)
    3282             : {
    3283             :     // get the type of the expression, as far as easily possible
    3284           0 :     OQueryController& rController = static_cast<OQueryController&>(getController());
    3285           0 :     sal_Int32 nDataType = DataType::DOUBLE;
    3286           0 :     switch(pNode->getNodeType())
    3287             :     {
    3288             :     case SQL_NODE_CONCAT:
    3289             :     case SQL_NODE_STRING:
    3290           0 :         nDataType = DataType::VARCHAR;
    3291           0 :         break;
    3292             :     case SQL_NODE_INTNUM:
    3293           0 :         nDataType = DataType::INTEGER;
    3294           0 :         break;
    3295             :     case SQL_NODE_APPROXNUM:
    3296           0 :         nDataType = DataType::DOUBLE;
    3297           0 :         break;
    3298             :     case SQL_NODE_DATE:
    3299             :     case SQL_NODE_ACCESS_DATE:
    3300           0 :         nDataType = DataType::TIMESTAMP;
    3301           0 :         break;
    3302             :     case SQL_NODE_COMPARISON:
    3303             :     case SQL_NODE_EQUAL:
    3304             :     case SQL_NODE_LESS:
    3305             :     case SQL_NODE_GREAT:
    3306             :     case SQL_NODE_LESSEQ:
    3307             :     case SQL_NODE_GREATEQ:
    3308             :     case SQL_NODE_NOTEQUAL:
    3309           0 :         nDataType = DataType::BOOLEAN;
    3310           0 :         break;
    3311             :     case SQL_NODE_NAME:
    3312             :     case SQL_NODE_LISTRULE:
    3313             :     case SQL_NODE_COMMALISTRULE:
    3314             :     case SQL_NODE_KEYWORD:
    3315             :     case SQL_NODE_AMMSC: //??
    3316             :     case SQL_NODE_PUNCTUATION:
    3317             :         OSL_FAIL("Unexpected SQL Node Type");
    3318           0 :         break;
    3319             :     case SQL_NODE_RULE:
    3320           0 :         switch(pNode->getKnownRuleID())
    3321             :         {
    3322             :         case OSQLParseNode::select_statement:
    3323             :         case OSQLParseNode::table_exp:
    3324             :         case OSQLParseNode::table_ref_commalist:
    3325             :         case OSQLParseNode::table_ref:
    3326             :         case OSQLParseNode::catalog_name:
    3327             :         case OSQLParseNode::schema_name:
    3328             :         case OSQLParseNode::table_name:
    3329             :         case OSQLParseNode::opt_column_commalist:
    3330             :         case OSQLParseNode::column_commalist:
    3331             :         case OSQLParseNode::column_ref_commalist:
    3332             :         case OSQLParseNode::column_ref:
    3333             :         case OSQLParseNode::opt_order_by_clause:
    3334             :         case OSQLParseNode::ordering_spec_commalist:
    3335             :         case OSQLParseNode::ordering_spec:
    3336             :         case OSQLParseNode::opt_asc_desc:
    3337             :         case OSQLParseNode::where_clause:
    3338             :         case OSQLParseNode::opt_where_clause:
    3339             :         case OSQLParseNode::opt_escape:
    3340             :         case OSQLParseNode::scalar_exp_commalist:
    3341             :         case OSQLParseNode::scalar_exp: // Seems to never be generated?
    3342             :         case OSQLParseNode::parameter_ref:
    3343             :         case OSQLParseNode::parameter:
    3344             :         case OSQLParseNode::range_variable:
    3345             :         case OSQLParseNode::delete_statement_positioned:
    3346             :         case OSQLParseNode::delete_statement_searched:
    3347             :         case OSQLParseNode::update_statement_positioned:
    3348             :         case OSQLParseNode::update_statement_searched:
    3349             :         case OSQLParseNode::assignment_commalist:
    3350             :         case OSQLParseNode::assignment:
    3351             :         case OSQLParseNode::insert_statement:
    3352             :         case OSQLParseNode::insert_atom_commalist:
    3353             :         case OSQLParseNode::insert_atom:
    3354             :         case OSQLParseNode::from_clause:
    3355             :         case OSQLParseNode::qualified_join:
    3356             :         case OSQLParseNode::cross_union:
    3357             :         case OSQLParseNode::select_sublist:
    3358             :         case OSQLParseNode::join_type:
    3359             :         case OSQLParseNode::named_columns_join:
    3360             :         case OSQLParseNode::joined_table:
    3361             :         case OSQLParseNode::sql_not:
    3362             :         case OSQLParseNode::manipulative_statement:
    3363             :         case OSQLParseNode::value_exp_commalist:
    3364             :         case OSQLParseNode::union_statement:
    3365             :         case OSQLParseNode::outer_join_type:
    3366             :         case OSQLParseNode::selection:
    3367             :         case OSQLParseNode::base_table_def:
    3368             :         case OSQLParseNode::base_table_element_commalist:
    3369             :         case OSQLParseNode::data_type:
    3370             :         case OSQLParseNode::column_def:
    3371             :         case OSQLParseNode::table_node:
    3372             :         case OSQLParseNode::as:  // Seems to never be generated?
    3373             :         case OSQLParseNode::op_column_commalist:
    3374             :         case OSQLParseNode::table_primary_as_range_column:
    3375             :         case OSQLParseNode::character_string_type:
    3376             :             OSL_FAIL("Unexpected SQL RuleID");
    3377           0 :             break;
    3378             :         case OSQLParseNode::column:
    3379             :         case OSQLParseNode::column_val:
    3380             :             OSL_FAIL("Cannot guess column type");
    3381           0 :             break;
    3382             :         case OSQLParseNode::values_or_query_spec:
    3383             :             OSL_FAIL("Cannot guess VALUES type");
    3384           0 :             break;
    3385             :         case OSQLParseNode::derived_column:
    3386             :             OSL_FAIL("Cannot guess computed column type");
    3387           0 :             break;
    3388             :         case OSQLParseNode::subquery:
    3389             :             OSL_FAIL("Cannot guess subquery return type");
    3390           0 :             break;
    3391             :         case OSQLParseNode::search_condition:
    3392             :         case OSQLParseNode::comparison_predicate:
    3393             :         case OSQLParseNode::between_predicate:
    3394             :         case OSQLParseNode::like_predicate:
    3395             :         case OSQLParseNode::test_for_null:
    3396             :         case OSQLParseNode::predicate_check: // Seems to never be generated?
    3397             :         case OSQLParseNode::boolean_term:
    3398             :         case OSQLParseNode::boolean_primary:
    3399             :         case OSQLParseNode::in_predicate:
    3400             :         case OSQLParseNode::existence_test:
    3401             :         case OSQLParseNode::unique_test:
    3402             :         case OSQLParseNode::all_or_any_predicate:
    3403             :         case OSQLParseNode::join_condition:
    3404             :         case OSQLParseNode::boolean_factor:
    3405             :         case OSQLParseNode::boolean_test:
    3406             :         case OSQLParseNode::comparison_predicate_part_2:
    3407             :         case OSQLParseNode::parenthesized_boolean_value_expression:
    3408             :         case OSQLParseNode::other_like_predicate_part_2:
    3409             :         case OSQLParseNode::between_predicate_part_2:
    3410           0 :             nDataType = DataType::BOOLEAN;
    3411           0 :             break;
    3412             :         case OSQLParseNode::num_value_exp:
    3413             :         case OSQLParseNode::extract_exp:
    3414             :         case OSQLParseNode::term:
    3415             :         case OSQLParseNode::factor:
    3416             :             // Might by an integer or a float; take the most generic
    3417           0 :             nDataType = DataType::DOUBLE;
    3418           0 :             break;
    3419             :         case OSQLParseNode::value_exp_primary:
    3420             :         case OSQLParseNode::value_exp:
    3421             :         case OSQLParseNode::odbc_call_spec:
    3422             :             // Really, we don't know. Let the default.
    3423           0 :             break;
    3424             :         case OSQLParseNode::position_exp:
    3425             :         case OSQLParseNode::length_exp:
    3426           0 :             nDataType = DataType::INTEGER;
    3427           0 :             break;
    3428             :         case OSQLParseNode::char_value_exp:
    3429             :         case OSQLParseNode::char_value_fct:
    3430             :         case OSQLParseNode::fold:
    3431             :         case OSQLParseNode::char_substring_fct:
    3432             :         case OSQLParseNode::char_factor:
    3433             :         case OSQLParseNode::concatenation:
    3434           0 :             nDataType = DataType::VARCHAR;
    3435           0 :             break;
    3436             :         case OSQLParseNode::datetime_primary:
    3437           0 :             nDataType = DataType::TIMESTAMP;
    3438           0 :             break;
    3439             :         case OSQLParseNode::bit_value_fct:
    3440           0 :             nDataType = DataType::BINARY;
    3441           0 :             break;
    3442             :         case OSQLParseNode::general_set_fct: // May depend on argument; ignore that for now
    3443             :         case OSQLParseNode::set_fct_spec:
    3444             :         {
    3445           0 :             if (pNode->count() == 0)
    3446             :             {
    3447             :                 // This is not a function call, no sense to continue with a function return type lookup
    3448             :                 OSL_FAIL("Got leaf SQL node where non-leaf expected");
    3449           0 :                 break;
    3450             :             }
    3451           0 :             const OSQLParseNode* pFunctionName = pNode->getChild(0);
    3452           0 :             if ( SQL_ISPUNCTUATION(pFunctionName,"{") )
    3453             :             {
    3454           0 :                 if ( pNode->count() == 3 )
    3455           0 :                     return fillFunctionInfo( pNode->getChild(1), sFunctionTerm, aInfo );
    3456             :                 else
    3457             :                     OSL_FAIL("ODBC escape not in recognised form");
    3458           0 :                 break;
    3459             :             }
    3460             :             else
    3461             :             {
    3462           0 :                 if ( SQL_ISRULEOR2(pNode,length_exp,char_value_fct) )
    3463           0 :                     pFunctionName = pFunctionName->getChild(0);
    3464             : 
    3465           0 :                 ::rtl::OUString sFunctionName = pFunctionName->getTokenValue();
    3466           0 :                 if ( sFunctionName.isEmpty() )
    3467           0 :                     sFunctionName = ::rtl::OStringToOUString(OSQLParser::TokenIDToStr(pFunctionName->getTokenID()),RTL_TEXTENCODING_UTF8);
    3468             : 
    3469             :                 nDataType = OSQLParser::getFunctionReturnType(
    3470             :                     sFunctionName
    3471           0 :                     ,&rController.getParser().getContext());
    3472             :             }
    3473           0 :             break;
    3474             :         }
    3475             :         case OSQLParseNode::odbc_fct_spec:
    3476             :         {
    3477           0 :             if (pNode->count() != 2)
    3478             :             {
    3479             :                 OSL_FAIL("interior of ODBC escape not in recognised shape");
    3480           0 :                 break;
    3481             :             }
    3482             : 
    3483           0 :             const OSQLParseNode* const pEscapeType = pNode->getChild(0);
    3484           0 :             if (SQL_ISTOKEN(pEscapeType, TS))
    3485           0 :                 nDataType = DataType::TIMESTAMP;
    3486           0 :             else if (SQL_ISTOKEN(pEscapeType, D))
    3487           0 :                 nDataType = DataType::DATE;
    3488           0 :             else if (SQL_ISTOKEN(pEscapeType, T))
    3489           0 :                 nDataType = DataType::TIME;
    3490           0 :             else if (SQL_ISTOKEN(pEscapeType, FN))
    3491           0 :                 return fillFunctionInfo( pNode->getChild(1), sFunctionTerm, aInfo );
    3492             :             else
    3493             :                 OSL_FAIL("Unknown ODBC escape");
    3494           0 :             break;
    3495             :         }
    3496             :         case OSQLParseNode::cast_spec:
    3497             :         {
    3498           0 :             if ( pNode->count() != 6 || !SQL_ISTOKEN(pNode->getChild(3), AS) )
    3499             :             {
    3500             :                 OSL_FAIL("CAST not in recognised shape");
    3501           0 :                 break;
    3502             :             }
    3503           0 :             const OSQLParseNode *pCastTarget = pNode->getChild(4);
    3504           0 :             if ( SQL_ISTOKENOR2(pCastTarget, INTEGER, INT) )
    3505           0 :                 nDataType = DataType::INTEGER;
    3506           0 :             else if ( SQL_ISTOKEN(pCastTarget, SMALLINT) )
    3507           0 :                 nDataType = DataType::SMALLINT;
    3508           0 :             else if ( SQL_ISTOKEN(pCastTarget, BIGINT) )
    3509           0 :                 nDataType = DataType::BIGINT;
    3510           0 :             else if ( SQL_ISTOKEN(pCastTarget, FLOAT) )
    3511           0 :                 nDataType = DataType::FLOAT;
    3512           0 :             else if ( SQL_ISTOKEN(pCastTarget, REAL) )
    3513           0 :                 nDataType = DataType::REAL;
    3514           0 :            else if ( SQL_ISTOKEN(pCastTarget, DOUBLE) )
    3515           0 :                 nDataType = DataType::DOUBLE;
    3516           0 :             else if ( SQL_ISTOKEN(pCastTarget, BOOLEAN) )
    3517           0 :                 nDataType = DataType::BOOLEAN;
    3518           0 :             else if ( SQL_ISTOKEN(pCastTarget, DATE) )
    3519           0 :                 nDataType = DataType::DATE;
    3520           0 :             else if ( pCastTarget->count() > 0 )
    3521             :             {
    3522           0 :                 const OSQLParseNode *pDataType = pCastTarget->getChild(0);
    3523           0 :                 while (pDataType->count() > 0)
    3524             :                 {
    3525           0 :                     pCastTarget = pDataType;
    3526           0 :                     pDataType = pDataType->getChild(0);
    3527             :                 }
    3528           0 :                 if ( SQL_ISTOKEN (pDataType, TIME) )
    3529           0 :                     nDataType = DataType::TIME;
    3530           0 :                 else if ( SQL_ISTOKEN (pDataType, TIMESTAMP) )
    3531           0 :                     nDataType = DataType::TIMESTAMP;
    3532           0 :                 else if ( SQL_ISTOKENOR3 (pDataType, CHARACTER, CHAR, NCHAR) )
    3533           0 :                     nDataType = char_datatype(pCastTarget, 0);
    3534           0 :                 else if ( SQL_ISTOKEN (pDataType, VARCHAR) )
    3535           0 :                     nDataType = DataType::VARCHAR;
    3536           0 :                 else if ( SQL_ISTOKEN (pDataType, CLOB) )
    3537           0 :                     nDataType = DataType::CLOB;
    3538           0 :                 else if ( SQL_ISTOKEN (pDataType, NATIONAL) )
    3539           0 :                     nDataType = char_datatype(pCastTarget, 1);
    3540           0 :                 else if ( SQL_ISTOKEN (pDataType, BINARY) )
    3541             :                 {
    3542           0 :                     if ( pCastTarget->count() > 2 && SQL_ISTOKEN(pCastTarget->getChild(1), LARGE) && SQL_ISTOKEN(pCastTarget->getChild(2), OBJECT) )
    3543           0 :                         nDataType = DataType::BLOB;
    3544           0 :                     else if ( pCastTarget->count() > 1 && SQL_ISTOKEN(pCastTarget->getChild(1), VARYING) )
    3545           0 :                         nDataType = DataType::VARBINARY;
    3546             :                     else
    3547           0 :                         nDataType = DataType::BINARY;
    3548             :                 }
    3549           0 :                 else if ( SQL_ISTOKEN (pDataType, VARBINARY) )
    3550           0 :                     nDataType = DataType::VARBINARY;
    3551           0 :                 else if ( SQL_ISTOKEN (pDataType, BLOB) )
    3552           0 :                     nDataType = DataType::BLOB;
    3553           0 :                 else if ( SQL_ISTOKEN (pDataType, NUMERIC) )
    3554           0 :                     nDataType = DataType::NUMERIC;
    3555           0 :                 else if ( SQL_ISTOKENOR2 (pDataType, DECIMAL, DEC) )
    3556           0 :                     nDataType = DataType::DECIMAL;
    3557           0 :                 else if ( SQL_ISTOKEN (pDataType, FLOAT) )
    3558           0 :                     nDataType = DataType::FLOAT;
    3559           0 :                 else if ( SQL_ISTOKEN (pDataType, DOUBLE) )
    3560           0 :                     nDataType = DataType::DOUBLE;
    3561           0 :                 else if ( SQL_ISTOKEN (pDataType, TIME) )
    3562           0 :                     nDataType = DataType::TIME;
    3563           0 :                 else if ( SQL_ISTOKEN (pDataType, TIMESTAMP) )
    3564           0 :                     nDataType = DataType::TIMESTAMP;
    3565           0 :                 else if ( SQL_ISTOKEN (pDataType, INTERVAL) )
    3566             :                     // Not in DataType published constant (because not in JDBC...)
    3567           0 :                     nDataType = DataType::VARCHAR;
    3568             :                 else
    3569             :                     OSL_FAIL("Failed to decode CAST target");
    3570             :             }
    3571             :             else
    3572             :                 OSL_FAIL("Could not decipher CAST target");
    3573           0 :             break;
    3574             :         }
    3575             :         default:
    3576             :             OSL_FAIL("Unknown SQL RuleID");
    3577           0 :             break;
    3578             :         }
    3579           0 :         break;
    3580             :     default:
    3581             :         OSL_FAIL("Unknown SQL Node Type");
    3582           0 :         break;
    3583             :     }
    3584             : 
    3585           0 :     aInfo->SetDataType(nDataType);
    3586           0 :     aInfo->SetFieldType(TAB_NORMAL_FIELD);
    3587           0 :     aInfo->SetField(sFunctionTerm);
    3588           0 :     aInfo->SetTabWindow(NULL);
    3589           0 : }
    3590             : // -----------------------------------------------------------------------------
    3591             : 
    3592             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10