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

Generated by: LCOV version 1.10