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

Generated by: LCOV version 1.11