LCOV - code coverage report
Current view: top level - dbaccess/source/core/api - SingleSelectQueryComposer.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 628 947 66.3 %
Date: 2014-11-03 Functions: 66 70 94.3 %
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 <string.h>
      21             : #include "composertools.hxx"
      22             : #include "core_resource.hrc"
      23             : #include "core_resource.hxx"
      24             : #include "dbastrings.hrc"
      25             : #include "HelperCollections.hxx"
      26             : #include "SingleSelectQueryComposer.hxx"
      27             : #include "sdbcoretools.hxx"
      28             : 
      29             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      30             : #include <com/sun/star/container/XChild.hpp>
      31             : #include <com/sun/star/i18n/LocaleData.hpp>
      32             : #include <com/sun/star/lang/DisposedException.hpp>
      33             : #include <com/sun/star/script/Converter.hpp>
      34             : #include <com/sun/star/sdb/BooleanComparisonMode.hpp>
      35             : #include <com/sun/star/sdb/SQLFilterOperator.hpp>
      36             : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
      37             : #include <com/sun/star/sdb/CommandType.hpp>
      38             : #include <com/sun/star/sdbc/ColumnSearch.hpp>
      39             : #include <com/sun/star/sdbc/DataType.hpp>
      40             : #include <com/sun/star/sdbc/XResultSetMetaData.hpp>
      41             : #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
      42             : #include <com/sun/star/sdbc/XParameters.hpp>
      43             : #include <com/sun/star/uno/XAggregation.hpp>
      44             : #include <com/sun/star/util/NumberFormatter.hpp>
      45             : 
      46             : #include <comphelper/processfactory.hxx>
      47             : #include <comphelper/sequence.hxx>
      48             : #include <comphelper/types.hxx>
      49             : #include <cppuhelper/exc_hlp.hxx>
      50             : #include <cppuhelper/typeprovider.hxx>
      51             : #include <connectivity/predicateinput.hxx>
      52             : #include <unotools/syslocale.hxx>
      53             : #include <tools/debug.hxx>
      54             : #include <tools/diagnose_ex.h>
      55             : #include <osl/diagnose.h>
      56             : #include <unotools/configmgr.hxx>
      57             : #include <unotools/sharedunocomponent.hxx>
      58             : 
      59             : #include <boost/scoped_ptr.hpp>
      60             : 
      61             : using namespace ::dbaccess;
      62             : using namespace ::dbtools;
      63             : using namespace ::comphelper;
      64             : using namespace ::connectivity;
      65             : using namespace ::com::sun::star::uno;
      66             : using namespace ::com::sun::star::beans;
      67             : using namespace ::com::sun::star::sdbc;
      68             : using namespace ::com::sun::star::sdb;
      69             : using namespace ::com::sun::star::sdbcx;
      70             : using namespace ::com::sun::star::container;
      71             : using namespace ::com::sun::star::i18n;
      72             : using namespace ::com::sun::star::lang;
      73             : using namespace ::com::sun::star::script;
      74             : using namespace ::com::sun::star::util;
      75             : using namespace ::cppu;
      76             : using namespace ::osl;
      77             : using namespace ::utl;
      78             : 
      79             : namespace dbaccess {
      80             : namespace BooleanComparisonMode = ::com::sun::star::sdb::BooleanComparisonMode;
      81             : }
      82             : 
      83             : #define STR_SELECT      "SELECT "
      84             : #define STR_FROM        " FROM "
      85             : #define STR_WHERE       " WHERE "
      86             : #define STR_GROUP_BY    " GROUP BY "
      87             : #define STR_HAVING      " HAVING "
      88             : #define STR_ORDER_BY    " ORDER BY "
      89             : #define STR_AND         " AND "
      90             : #define STR_OR          " OR "
      91             : #define STR_LIKE        OUString(" LIKE ")
      92             : #define L_BRACKET       "("
      93             : #define R_BRACKET       ")"
      94             : #define COMMA           ","
      95             : 
      96             : namespace
      97             : {
      98             :     /** parses the given statement, using the given parser, returns a parse node representing
      99             :         the statement
     100             : 
     101             :         If the statement cannot be parsed, an error is thrown.
     102             :     */
     103         294 :     const OSQLParseNode* parseStatement_throwError( OSQLParser& _rParser, const OUString& _rStatement, const Reference< XInterface >& _rxContext )
     104             :     {
     105         294 :         OUString aErrorMsg;
     106         294 :         const OSQLParseNode* pNewSqlParseNode = _rParser.parseTree( aErrorMsg, _rStatement );
     107         294 :         if ( !pNewSqlParseNode )
     108             :         {
     109           2 :             OUString sSQLStateGeneralError( getStandardSQLState( SQL_GENERAL_ERROR ) );
     110           4 :             SQLException aError2( aErrorMsg, _rxContext, sSQLStateGeneralError, 1000, Any() );
     111           4 :             SQLException aError1( _rStatement, _rxContext, sSQLStateGeneralError, 1000, makeAny( aError2 ) );
     112           4 :             throw SQLException(_rParser.getContext().getErrorMessage(OParseContext::ERROR_GENERAL),_rxContext,sSQLStateGeneralError,1000,makeAny(aError1));
     113             :         }
     114         294 :         return pNewSqlParseNode;
     115             :     }
     116             : 
     117             :     /** checks whether the given parse node describes a valid single select statement, throws
     118             :         an error if not
     119             :     */
     120         292 :     void checkForSingleSelect_throwError( const OSQLParseNode* pStatementNode, OSQLParseTreeIterator& _rIterator,
     121             :         const Reference< XInterface >& _rxContext, const OUString& _rOriginatingCommand )
     122             :     {
     123         292 :         const OSQLParseNode* pOldNode = _rIterator.getParseTree();
     124             : 
     125             :         // determine the statement type
     126         292 :         _rIterator.setParseTree( pStatementNode );
     127         292 :         _rIterator.traverseAll();
     128         292 :         bool bIsSingleSelect = ( _rIterator.getStatementType() == SQL_STATEMENT_SELECT );
     129             : 
     130             :         // throw the error, if necessary
     131         292 :         if ( !bIsSingleSelect || SQL_ISRULE( pStatementNode, union_statement ) ) // #i4229# OJ
     132             :         {
     133             :             // restore the old node before throwing the exception
     134           0 :             _rIterator.setParseTree( pOldNode );
     135             :             // and now really ...
     136           0 :             SQLException aError1( _rOriginatingCommand, _rxContext, getStandardSQLState( SQL_GENERAL_ERROR ), 1000, Any() );
     137             :             throw SQLException( DBACORE_RESSTRING( RID_STR_ONLY_QUERY ), _rxContext,
     138           0 :                 getStandardSQLState( SQL_GENERAL_ERROR ), 1000, makeAny( aError1 ) );
     139             :         }
     140             : 
     141         292 :         delete pOldNode;
     142         292 :     }
     143             : 
     144             :     /** combines parseStatement_throwError and checkForSingleSelect_throwError
     145             :     */
     146         294 :     void parseAndCheck_throwError( OSQLParser& _rParser, const OUString& _rStatement,
     147             :         OSQLParseTreeIterator& _rIterator, const Reference< XInterface >& _rxContext )
     148             :     {
     149         294 :         const OSQLParseNode* pNode = parseStatement_throwError( _rParser, _rStatement, _rxContext );
     150         292 :         checkForSingleSelect_throwError( pNode, _rIterator, _rxContext, _rStatement );
     151         292 :     }
     152             : 
     153             :     /** transforms a parse node describing a complete statement into a pure select
     154             :         statement, without any filter/order/groupby/having clauses
     155             :     */
     156         146 :     OUString getPureSelectStatement( const OSQLParseNode* _pRootNode, Reference< XConnection > _rxConnection )
     157             :     {
     158         146 :         OUString sSQL = STR_SELECT;
     159         146 :         _pRootNode->getChild(1)->parseNodeToStr( sSQL, _rxConnection );
     160         146 :         _pRootNode->getChild(2)->parseNodeToStr( sSQL, _rxConnection );
     161         146 :         sSQL += STR_FROM;
     162         146 :         _pRootNode->getChild(3)->getChild(0)->getChild(1)->parseNodeToStr( sSQL, _rxConnection );
     163         146 :         return sSQL;
     164             :     }
     165             : 
     166             :     /** resets an SQL iterator, including deletion of the parse tree, and disposal if desired
     167             :     */
     168         164 :     void resetIterator( OSQLParseTreeIterator& _rIterator, bool _bDispose )
     169             :     {
     170         164 :         const OSQLParseNode* pSqlParseNode = _rIterator.getParseTree();
     171         164 :         _rIterator.setParseTree(NULL);
     172         164 :         delete pSqlParseNode;
     173         164 :         if ( _bDispose )
     174         164 :             _rIterator.dispose();
     175         164 :     }
     176          78 :     void lcl_addFilterCriteria_throw(sal_Int32 i_nFilterOperator,const OUString& i_sValue,OUStringBuffer& o_sRet)
     177             :     {
     178          78 :         switch( i_nFilterOperator )
     179             :         {
     180             :             case SQLFilterOperator::EQUAL:
     181          78 :                 o_sRet.append(" = " + i_sValue);
     182          78 :                 break;
     183             :             case SQLFilterOperator::NOT_EQUAL:
     184           0 :                 o_sRet.append(" <> " + i_sValue);
     185           0 :                 break;
     186             :             case SQLFilterOperator::LESS:
     187           0 :                 o_sRet.append(" < " + i_sValue);
     188           0 :                 break;
     189             :             case SQLFilterOperator::GREATER:
     190           0 :                 o_sRet.append(" > " + i_sValue);
     191           0 :                 break;
     192             :             case SQLFilterOperator::LESS_EQUAL:
     193           0 :                 o_sRet.append(" <= " + i_sValue);
     194           0 :                 break;
     195             :             case SQLFilterOperator::GREATER_EQUAL:
     196           0 :                 o_sRet.append(" >= " + i_sValue);
     197           0 :                 break;
     198             :             case SQLFilterOperator::LIKE:
     199           0 :                 o_sRet.append(" LIKE " + i_sValue);
     200           0 :                 break;
     201             :             case SQLFilterOperator::NOT_LIKE:
     202           0 :                 o_sRet.append(" NOT LIKE " + i_sValue);
     203           0 :                 break;
     204             :             case SQLFilterOperator::SQLNULL:
     205           0 :                 o_sRet.append(" IS NULL");
     206           0 :                 break;
     207             :             case SQLFilterOperator::NOT_SQLNULL:
     208           0 :                 o_sRet.append(" IS NOT NULL");
     209           0 :                 break;
     210             :             default:
     211           0 :                 throw SQLException();
     212             :         }
     213          78 :     }
     214             : 
     215             : }
     216             : 
     217             : 
     218          82 : OSingleSelectQueryComposer::OSingleSelectQueryComposer(const Reference< XNameAccess>& _rxTables,
     219             :                                const Reference< XConnection>& _xConnection,
     220             :                                const Reference<XComponentContext>& _rContext )
     221             :     :OSubComponent(m_aMutex,_xConnection)
     222             :     ,OPropertyContainer(m_aBHelper)
     223             :     ,m_aSqlParser( _rContext, &m_aParseContext )
     224             :     ,m_aSqlIterator( _xConnection, _rxTables, m_aSqlParser, NULL )
     225             :     ,m_aAdditiveIterator( _xConnection, _rxTables, m_aSqlParser, NULL )
     226             :     ,m_aElementaryParts( (size_t)SQLPartCount )
     227             :     ,m_xConnection(_xConnection)
     228          82 :     ,m_xMetaData(_xConnection->getMetaData())
     229             :     ,m_xConnectionTables( _rxTables )
     230             :     ,m_aContext( _rContext )
     231             :     ,m_pTables(NULL)
     232             :     ,m_nBoolCompareMode( BooleanComparisonMode::EQUAL_INTEGER )
     233         164 :     ,m_nCommandType(CommandType::COMMAND)
     234             : {
     235          82 :     if ( !m_aContext.is() || !m_xConnection.is() || !m_xConnectionTables.is() )
     236           0 :         throw IllegalArgumentException();
     237             : 
     238          82 :     registerProperty(PROPERTY_ORIGINAL,PROPERTY_ID_ORIGINAL,PropertyAttribute::BOUND|PropertyAttribute::READONLY,&m_sOrignal,::getCppuType(&m_sOrignal));
     239             : 
     240          82 :     m_aCurrentColumns.resize(4);
     241             : 
     242          82 :     m_aLocale = m_aParseContext.getPreferredLocale();
     243          82 :     m_xNumberFormatsSupplier = dbtools::getNumberFormats( m_xConnection, true, m_aContext );
     244          82 :     Reference< XLocaleData4 > xLocaleData( LocaleData::create(m_aContext) );
     245         164 :     LocaleDataItem aData = xLocaleData->getLocaleItem(m_aLocale);
     246          82 :     m_sDecimalSep = aData.decimalSeparator;
     247             :     OSL_ENSURE(m_sDecimalSep.getLength() == 1,"OSingleSelectQueryComposer::OSingleSelectQueryComposer decimal separator is not 1 length");
     248             :     try
     249             :     {
     250          82 :         Any aValue;
     251         164 :         Reference<XInterface> xDs = dbaccess::getDataSource(_xConnection);
     252          82 :         if ( dbtools::getDataSourceSetting(xDs,static_cast <OUString> (PROPERTY_BOOLEANCOMPARISONMODE),aValue) )
     253             :         {
     254          82 :             OSL_VERIFY( aValue >>= m_nBoolCompareMode );
     255             :         }
     256         164 :         Reference< XQueriesSupplier >  xQueriesAccess(m_xConnection, UNO_QUERY);
     257          82 :         if (xQueriesAccess.is())
     258         164 :             m_xConnectionQueries = xQueriesAccess->getQueries();
     259             :     }
     260           0 :     catch(Exception&)
     261             :     {
     262          82 :     }
     263          82 : }
     264             : 
     265         246 : OSingleSelectQueryComposer::~OSingleSelectQueryComposer()
     266             : {
     267          82 :     ::std::vector<OPrivateColumns*>::iterator aColIter = m_aColumnsCollection.begin();
     268          82 :     ::std::vector<OPrivateColumns*>::iterator aEnd = m_aColumnsCollection.end();
     269         234 :     for(;aColIter != aEnd;++aColIter)
     270         152 :         delete *aColIter;
     271             : 
     272          82 :     ::std::vector<OPrivateTables*>::iterator aTabIter = m_aTablesCollection.begin();
     273          82 :     ::std::vector<OPrivateTables*>::iterator aTabEnd = m_aTablesCollection.end();
     274         174 :     for(;aTabIter != aTabEnd;++aTabIter)
     275          92 :         delete *aTabIter;
     276         164 : }
     277             : 
     278             : // OComponentHelper
     279          82 : void SAL_CALL OSingleSelectQueryComposer::disposing(void)
     280             : {
     281          82 :     OSubComponent::disposing();
     282             : 
     283          82 :     MutexGuard aGuard(m_aMutex);
     284             : 
     285          82 :     resetIterator( m_aSqlIterator, true );
     286          82 :     resetIterator( m_aAdditiveIterator, true );
     287             : 
     288          82 :     m_xConnectionTables = NULL;
     289          82 :     m_xConnection       = NULL;
     290             : 
     291          82 :     clearCurrentCollections();
     292          82 : }
     293             : 
     294        9694 : IMPLEMENT_FORWARD_XINTERFACE3(OSingleSelectQueryComposer,OSubComponent,OSingleSelectQueryComposer_BASE,OPropertyContainer)
     295           6 : IMPLEMENT_SERVICE_INFO1(OSingleSelectQueryComposer,"org.openoffice.comp.dba.OSingleSelectQueryComposer",SERVICE_NAME_SINGLESELECTQUERYCOMPOSER)
     296             : 
     297           0 : css::uno::Sequence<sal_Int8> OSingleSelectQueryComposer::getImplementationId()
     298             :     throw (css::uno::RuntimeException, std::exception)
     299             : {
     300           0 :     return css::uno::Sequence<sal_Int8>();
     301             : }
     302             : 
     303           0 : IMPLEMENT_GETTYPES3(OSingleSelectQueryComposer,OSubComponent,OSingleSelectQueryComposer_BASE,OPropertyContainer)
     304          22 : IMPLEMENT_PROPERTYCONTAINER_DEFAULTS(OSingleSelectQueryComposer)
     305             : 
     306             : // XSingleSelectQueryAnalyzer
     307         158 : OUString SAL_CALL OSingleSelectQueryComposer::getQuery(  ) throw(RuntimeException, std::exception)
     308             : {
     309         158 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
     310         158 :     ::osl::MutexGuard aGuard( m_aMutex );
     311             : 
     312         158 :     TGetParseNode F_tmp(&OSQLParseTreeIterator::getParseTree);
     313         158 :     return getStatementPart(F_tmp,m_aSqlIterator);
     314             : }
     315             : 
     316          18 : void SAL_CALL OSingleSelectQueryComposer::setQuery( const OUString& command ) throw(SQLException, RuntimeException, std::exception)
     317             : {
     318          18 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
     319             : 
     320          18 :     ::osl::MutexGuard aGuard( m_aMutex );
     321          18 :     m_nCommandType = CommandType::COMMAND;
     322             :     // first clear the tables and columns
     323          18 :     clearCurrentCollections();
     324             :     // now set the new one
     325          18 :     setQuery_Impl(command);
     326          16 :     m_sOrignal = command;
     327             : 
     328             :     // reset the additive iterator to the same statement
     329          16 :     parseAndCheck_throwError( m_aSqlParser, m_sOrignal, m_aAdditiveIterator, *this );
     330             : 
     331             :     // we have no "elementary" parts anymore (means filter/groupby/having/order clauses)
     332          80 :     for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
     333          82 :         m_aElementaryParts[ eLoopParts ] = OUString();
     334          16 : }
     335             : 
     336          42 : void SAL_CALL OSingleSelectQueryComposer::setCommand( const OUString& Command,sal_Int32 _nCommandType ) throw(SQLException, RuntimeException, std::exception)
     337             : {
     338          42 :     OUStringBuffer sSQL;
     339          42 :     switch(_nCommandType)
     340             :     {
     341             :         case CommandType::COMMAND:
     342          14 :             setElementaryQuery(Command);
     343          56 :             return;
     344             :         case CommandType::TABLE:
     345          28 :             if ( m_xConnectionTables->hasByName(Command) )
     346             :             {
     347          28 :                 sSQL.appendAscii("SELECT * FROM ");
     348          28 :                 Reference< XPropertySet > xTable;
     349             :                 try
     350             :                 {
     351          28 :                     m_xConnectionTables->getByName( Command ) >>= xTable;
     352             :                 }
     353           0 :                 catch(const WrappedTargetException& e)
     354             :                 {
     355           0 :                     SQLException e2;
     356           0 :                     if ( e.TargetException >>= e2 )
     357           0 :                         throw e2;
     358             :                 }
     359           0 :                 catch(Exception&)
     360             :                 {
     361             :                     DBG_UNHANDLED_EXCEPTION();
     362             :                 }
     363             : 
     364          28 :                 sSQL.append(dbtools::composeTableNameForSelect(m_xConnection,xTable));
     365             :             }
     366             :             else
     367             :             {
     368           0 :                 OUString sMessage( DBACORE_RESSTRING( RID_STR_TABLE_DOES_NOT_EXIST ) );
     369           0 :                 throwGenericSQLException(sMessage.replaceAll( "$table$", Command ),*this);
     370             :             }
     371          28 :             break;
     372             :         case CommandType::QUERY:
     373           0 :             if ( m_xConnectionQueries->hasByName(Command) )
     374             :             {
     375             : 
     376           0 :                 Reference<XPropertySet> xQuery(m_xConnectionQueries->getByName(Command),UNO_QUERY);
     377           0 :                 OUString sCommand;
     378           0 :                 xQuery->getPropertyValue(PROPERTY_COMMAND) >>= sCommand;
     379           0 :                 sSQL.append(sCommand);
     380             :             }
     381             :             else
     382             :             {
     383           0 :                 OUString sMessage( DBACORE_RESSTRING( RID_STR_QUERY_DOES_NOT_EXIST ) );
     384           0 :                 throwGenericSQLException(sMessage.replaceAll( "$table$", Command ),*this);
     385             :             }
     386             : 
     387           0 :             break;
     388             :         default:
     389           0 :             break;
     390             :     }
     391          28 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
     392             : 
     393          28 :     ::osl::MutexGuard aGuard( m_aMutex );
     394          28 :     m_nCommandType = _nCommandType;
     395          28 :     m_sCommand = Command;
     396             :     // first clear the tables and columns
     397          28 :     clearCurrentCollections();
     398             :     // now set the new one
     399          56 :     OUString sCommand = sSQL.makeStringAndClear();
     400          28 :     setElementaryQuery(sCommand);
     401          56 :     m_sOrignal = sCommand;
     402             : }
     403             : 
     404         148 : void OSingleSelectQueryComposer::setQuery_Impl( const OUString& command )
     405             : {
     406             :     // parse this
     407         150 :     parseAndCheck_throwError( m_aSqlParser, command, m_aSqlIterator, *this );
     408             : 
     409             :     // strip it from all clauses, to have the pure SELECT statement
     410         146 :     m_aPureSelectSQL = getPureSelectStatement( m_aSqlIterator.getParseTree(), m_xConnection );
     411             : 
     412             :     // update tables
     413         146 :     getTables();
     414         146 : }
     415             : 
     416           4 : Sequence< Sequence< PropertyValue > > SAL_CALL OSingleSelectQueryComposer::getStructuredHavingClause(  ) throw (RuntimeException, std::exception)
     417             : {
     418           4 :     TGetParseNode F_tmp(&OSQLParseTreeIterator::getSimpleHavingTree);
     419           4 :     return getStructuredCondition(F_tmp);
     420             : }
     421             : 
     422           4 : Sequence< Sequence< PropertyValue > > SAL_CALL OSingleSelectQueryComposer::getStructuredFilter(  ) throw(RuntimeException, std::exception)
     423             : {
     424           4 :     TGetParseNode F_tmp(&OSQLParseTreeIterator::getSimpleWhereTree);
     425           4 :     return getStructuredCondition(F_tmp);
     426             : }
     427             : 
     428           6 : void SAL_CALL OSingleSelectQueryComposer::appendHavingClauseByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw (SQLException, WrappedTargetException, RuntimeException, std::exception)
     429             : {
     430           6 :     ::std::mem_fun1_t<bool,OSingleSelectQueryComposer,const OUString&> F_tmp(&OSingleSelectQueryComposer::implSetHavingClause);
     431           6 :     setConditionByColumn(column,andCriteria,F_tmp,filterOperator);
     432           2 : }
     433             : 
     434           8 : void SAL_CALL OSingleSelectQueryComposer::appendFilterByColumn( const Reference< XPropertySet >& column, sal_Bool andCriteria,sal_Int32 filterOperator ) throw(SQLException, WrappedTargetException, RuntimeException, std::exception)
     435             : {
     436           8 :     ::std::mem_fun1_t<bool,OSingleSelectQueryComposer,const OUString&> F_tmp(&OSingleSelectQueryComposer::implSetFilter);
     437           8 :     setConditionByColumn(column,andCriteria,F_tmp,filterOperator);
     438           4 : }
     439             : 
     440           4 : OUString OSingleSelectQueryComposer::impl_getColumnRealName_throw(const Reference< XPropertySet >& column, bool bGroupBy)
     441             : {
     442           4 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
     443             : 
     444           4 :     getColumns();
     445          14 :     if ( !column.is()
     446           2 :         || !m_aCurrentColumns[SelectColumns]
     447          16 :         || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME)
     448             :         )
     449             :         {
     450           2 :             OUString sError(DBACORE_RESSTRING(RID_STR_COLUMN_UNKNOWN_PROP));
     451           4 :             SQLException aErr(sError.replaceAll("%value", OUString(PROPERTY_NAME)),*this,SQLSTATE_GENERAL,1000,Any() );
     452           4 :             throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,makeAny(aErr) );
     453             :         }
     454             : 
     455           2 :     OUString aName, aNewName;
     456           2 :     column->getPropertyValue(PROPERTY_NAME)         >>= aName;
     457             : 
     458           4 :     if ( bGroupBy &&
     459           4 :          !m_xMetaData->supportsGroupByUnrelated() &&
     460           6 :          m_aCurrentColumns[SelectColumns] &&
     461           2 :          !m_aCurrentColumns[SelectColumns]->hasByName(aName) )
     462             :     {
     463           0 :         OUString sError(DBACORE_RESSTRING(RID_STR_COLUMN_MUST_VISIBLE));
     464           0 :         throw SQLException(sError.replaceAll("%name", aName),*this,SQLSTATE_GENERAL,1000,Any() );
     465             :     }
     466             : 
     467           4 :     OUString aQuote  = m_xMetaData->getIdentifierQuoteString();
     468           2 :     if ( m_aCurrentColumns[SelectColumns]->hasByName(aName) )
     469             :     {
     470           2 :         Reference<XPropertySet> xColumn;
     471           2 :         m_aCurrentColumns[SelectColumns]->getByName(aName) >>= xColumn;
     472             :         OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!");
     473             :         OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!");
     474             :         OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName("Function"),"Property FUNCTION not available!");
     475             : 
     476           4 :         OUString sRealName, sTableName;
     477           2 :         xColumn->getPropertyValue(PROPERTY_REALNAME)    >>= sRealName;
     478           2 :         xColumn->getPropertyValue(PROPERTY_TABLENAME)   >>= sTableName;
     479           2 :         bool bFunction = false;
     480           2 :         xColumn->getPropertyValue("Function") >>= bFunction;
     481           2 :         if ( sRealName == aName )
     482             :         {
     483           2 :             if ( bFunction )
     484           0 :                 aNewName = aName;
     485             :             else
     486             :             {
     487           2 :                 if(sTableName.indexOf('.',0) != -1)
     488             :                 {
     489           0 :                     OUString aCatlog,aSchema,aTable;
     490           0 :                     ::dbtools::qualifiedNameComponents(m_xMetaData,sTableName,aCatlog,aSchema,aTable,::dbtools::eInDataManipulation);
     491           0 :                     sTableName = ::dbtools::composeTableName( m_xMetaData, aCatlog, aSchema, aTable, true, ::dbtools::eInDataManipulation );
     492             :                 }
     493           2 :                 else if (!sTableName.isEmpty())
     494           2 :                     sTableName = ::dbtools::quoteName(aQuote,sTableName);
     495             : 
     496           2 :                 if(sTableName.isEmpty())
     497           0 :                     aNewName =  ::dbtools::quoteName(aQuote,sRealName);
     498             :                 else
     499           2 :                     aNewName =  sTableName + "." + ::dbtools::quoteName(aQuote,sRealName);
     500             :             }
     501             :         }
     502             :         else
     503           2 :             aNewName = ::dbtools::quoteName(aQuote,aName);
     504             :     }
     505             :     else
     506           0 :         aNewName = getTableAlias(column) + ::dbtools::quoteName(aQuote,aName);
     507           4 :     return aNewName;
     508             : }
     509             : 
     510           4 : OUString OSingleSelectQueryComposer::impl_getColumnName_throw(const Reference< XPropertySet >& column, bool bOrderBy)
     511             : {
     512           4 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
     513             : 
     514           4 :     getColumns();
     515          14 :     if ( !column.is()
     516           2 :         || !m_aCurrentColumns[SelectColumns]
     517          16 :         || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME)
     518             :         )
     519             :         {
     520           2 :             OUString sError(DBACORE_RESSTRING(RID_STR_COLUMN_UNKNOWN_PROP));
     521           4 :             SQLException aErr(sError.replaceAll("%value", OUString(PROPERTY_NAME)),*this,SQLSTATE_GENERAL,1000,Any() );
     522           4 :             throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,makeAny(aErr) );
     523             :         }
     524             : 
     525           2 :     OUString aName;
     526           2 :     column->getPropertyValue(PROPERTY_NAME)         >>= aName;
     527             : 
     528           4 :     const OUString aQuote  = m_xMetaData->getIdentifierQuoteString();
     529             : 
     530           4 :     if ( m_aCurrentColumns[SelectColumns] &&
     531           2 :          m_aCurrentColumns[SelectColumns]->hasByName(aName) )
     532             :     {
     533             :         // It is a column from the SELECT list, use it as such.
     534           2 :         return ::dbtools::quoteName(aQuote,aName);
     535             :     }
     536             : 
     537             :     // Nope, it is an unrelated column.
     538             :     // Is that supported?
     539           0 :     if ( bOrderBy &&
     540           0 :          !m_xMetaData->supportsOrderByUnrelated() )
     541             :     {
     542           0 :         OUString sError(DBACORE_RESSTRING(RID_STR_COLUMN_MUST_VISIBLE));
     543           0 :         throw SQLException(sError.replaceAll("%name", aName),*this,SQLSTATE_GENERAL,1000,Any() );
     544             :     }
     545             : 
     546             :     // We need to refer to it by its "real" name, that is by schemaName.tableName.columnNameInTable
     547           2 :     return impl_getColumnRealName_throw(column, false);
     548             : }
     549             : 
     550           4 : void SAL_CALL OSingleSelectQueryComposer::appendOrderByColumn( const Reference< XPropertySet >& column, sal_Bool ascending ) throw(SQLException, RuntimeException, std::exception)
     551             : {
     552           4 :     ::osl::MutexGuard aGuard( m_aMutex );
     553           6 :     OUString sColumnName( impl_getColumnName_throw(column, true) );
     554           4 :     OUString sOrder = getOrder();
     555           2 :     if ( !(sOrder.isEmpty() || sColumnName.isEmpty()) )
     556           0 :         sOrder += COMMA;
     557           2 :     sOrder += sColumnName;
     558           2 :     if ( !(ascending || sColumnName.isEmpty()) )
     559           0 :         sOrder += " DESC ";
     560             : 
     561           6 :     setOrder(sOrder);
     562           2 : }
     563             : 
     564           4 : void SAL_CALL OSingleSelectQueryComposer::appendGroupByColumn( const Reference< XPropertySet >& column) throw(SQLException, RuntimeException, std::exception)
     565             : {
     566           4 :     ::osl::MutexGuard aGuard( m_aMutex );
     567           6 :     OUString sColumnName( impl_getColumnRealName_throw(column, true) );
     568           4 :     OrderCreator aComposer;
     569           2 :     aComposer.append( getGroup() );
     570           2 :     aComposer.append( sColumnName );
     571           6 :     setGroup( aComposer.getComposedAndClear() );
     572           2 : }
     573             : 
     574          76 : OUString OSingleSelectQueryComposer::composeStatementFromParts( const ::std::vector< OUString >& _rParts )
     575             : {
     576             :     OSL_ENSURE( _rParts.size() == (size_t)SQLPartCount, "OSingleSelectQueryComposer::composeStatementFromParts: invalid parts array!" );
     577             : 
     578          76 :     OUStringBuffer aSql( m_aPureSelectSQL );
     579         380 :     for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
     580         304 :         if ( !_rParts[ eLoopParts ].isEmpty() )
     581             :         {
     582           0 :             aSql.append( getKeyword( eLoopParts ) );
     583           0 :             aSql.append( _rParts[ eLoopParts ] );
     584             :         }
     585             : 
     586          76 :     return aSql.makeStringAndClear();
     587             : }
     588             : 
     589           0 : OUString SAL_CALL OSingleSelectQueryComposer::getElementaryQuery() throw (::com::sun::star::uno::RuntimeException, std::exception)
     590             : {
     591           0 :     return composeStatementFromParts( m_aElementaryParts );
     592             : }
     593             : 
     594          76 : void SAL_CALL OSingleSelectQueryComposer::setElementaryQuery( const OUString& _rElementary ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException, std::exception)
     595             : {
     596          76 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
     597          76 :     ::osl::MutexGuard aGuard( m_aMutex );
     598             : 
     599             :     // remember the 4 current "additive" clauses
     600         152 :     ::std::vector< OUString > aAdditiveClauses( SQLPartCount );
     601         380 :     for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
     602         304 :         aAdditiveClauses[ eLoopParts ] = getSQLPart( eLoopParts, m_aAdditiveIterator, false );
     603             : 
     604             :     // clear the tables and columns
     605          76 :     clearCurrentCollections();
     606             :     // set and parse the new query
     607          76 :     setQuery_Impl( _rElementary );
     608             : 
     609             :     // get the 4 elementary parts of the statement
     610         380 :     for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
     611         304 :         m_aElementaryParts[ eLoopParts ] = getSQLPart( eLoopParts, m_aSqlIterator, false );
     612             : 
     613             :     // reset the AdditiveIterator: m_aPureSelectSQL may have changed
     614             :     try
     615             :     {
     616          76 :         parseAndCheck_throwError( m_aSqlParser, composeStatementFromParts( aAdditiveClauses ), m_aAdditiveIterator, *this );
     617             :     }
     618           0 :     catch( const Exception& e )
     619             :     {
     620             :         (void)e;
     621             :         SAL_WARN("dbaccess", "OSingleSelectQueryComposer::setElementaryQuery: there should be no error anymore for the additive statement!" );
     622             :         DBG_UNHANDLED_EXCEPTION();
     623             :         // every part of the additive statement should have passed other tests already, and should not
     624             :         // be able to cause any errors ... me thinks
     625          76 :     }
     626          76 : }
     627             : 
     628             : namespace
     629             : {
     630         108 :     OUString getComposedClause( const OUString& _rElementaryClause, const OUString& _rAdditionalClause,
     631             :         TokenComposer& _rComposer, const OUString& _rKeyword )
     632             :     {
     633         108 :         _rComposer.clear();
     634         108 :         _rComposer.append( _rElementaryClause );
     635         108 :         _rComposer.append( _rAdditionalClause );
     636         108 :         OUString sComposed = _rComposer.getComposedAndClear();
     637         108 :         if ( !sComposed.isEmpty() )
     638          92 :             sComposed = _rKeyword + sComposed;
     639         108 :         return sComposed;
     640             :     }
     641             : }
     642             : 
     643         284 : void OSingleSelectQueryComposer::setSingleAdditiveClause( SQLPart _ePart, const OUString& _rClause )
     644             : {
     645         284 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
     646         284 :     ::osl::MutexGuard aGuard( m_aMutex );
     647             : 
     648             :     // if nothing is changed, do nothing
     649         284 :     if ( getSQLPart( _ePart, m_aAdditiveIterator, false ) == _rClause )
     650         514 :         return;
     651             : 
     652             :     // collect the 4 single parts as they're currently set
     653         108 :     ::std::vector< OUString > aClauses;
     654          54 :     aClauses.reserve( (size_t)SQLPartCount );
     655         270 :     for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
     656         216 :         aClauses.push_back( getSQLPart( eLoopParts, m_aSqlIterator, true ) );
     657             : 
     658             :     // overwrite the one part in question here
     659         108 :     boost::scoped_ptr< TokenComposer > pComposer;
     660          54 :     if ( ( _ePart == Where ) || ( _ePart == Having ) )
     661          38 :         pComposer.reset( new FilterCreator );
     662             :     else
     663          16 :         pComposer.reset( new OrderCreator );
     664         162 :     aClauses[ _ePart ] = getComposedClause( m_aElementaryParts[ _ePart ], _rClause,
     665         108 :         *pComposer, getKeyword( _ePart ) );
     666             : 
     667             :     // construct the complete statement
     668         108 :     OUStringBuffer aSql(m_aPureSelectSQL);
     669         270 :     for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
     670         216 :         aSql.append(aClauses[ eLoopParts ]);
     671             : 
     672             :     // set the query
     673          54 :     setQuery_Impl(aSql.makeStringAndClear());
     674             : 
     675             :     // clear column collections which (might) have changed
     676          54 :     clearColumns( ParameterColumns );
     677          54 :     if ( _ePart == Order )
     678          10 :         clearColumns( OrderColumns );
     679          44 :     else if ( _ePart == Group )
     680           6 :         clearColumns( GroupByColumns );
     681             : 
     682             :     // also, since the "additive filter" change, we need to rebuild our "additive" statement
     683          54 :     aSql = m_aPureSelectSQL;
     684             :     // again, first get all the old additive parts
     685         270 :     for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
     686         216 :         aClauses[ eLoopParts ] = getSQLPart( eLoopParts, m_aAdditiveIterator, true );
     687             :     // then overwrite the one in question
     688          54 :     aClauses[ _ePart ] = getComposedClause( OUString(), _rClause, *pComposer, getKeyword( _ePart ) );
     689             :     // and parse it, so that m_aAdditiveIterator is up to date
     690         270 :     for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) )
     691         216 :         aSql.append(aClauses[ eLoopParts ]);
     692             :     try
     693             :     {
     694          54 :         parseAndCheck_throwError( m_aSqlParser, aSql.makeStringAndClear(), m_aAdditiveIterator, *this );
     695             :     }
     696           0 :     catch( const Exception& e )
     697             :     {
     698             :         (void)e;
     699             :         SAL_WARN("dbaccess", "OSingleSelectQueryComposer::setSingleAdditiveClause: there should be no error anymore for the additive statement!" );
     700             :         // every part of the additive statement should have passed other tests already, and should not
     701             :         // be able to cause any errors ... me thinks
     702          54 :     }
     703             : }
     704             : 
     705          96 : void SAL_CALL OSingleSelectQueryComposer::setFilter( const OUString& filter ) throw(SQLException, RuntimeException, std::exception)
     706             : {
     707          96 :     setSingleAdditiveClause( Where, filter );
     708          96 : }
     709             : 
     710          82 : void SAL_CALL OSingleSelectQueryComposer::setOrder( const OUString& order ) throw(SQLException, RuntimeException, std::exception)
     711             : {
     712          82 :     setSingleAdditiveClause( Order, order );
     713          82 : }
     714             : 
     715          46 : void SAL_CALL OSingleSelectQueryComposer::setGroup( const OUString& group ) throw (SQLException, RuntimeException, std::exception)
     716             : {
     717          46 :     setSingleAdditiveClause( Group, group );
     718          46 : }
     719             : 
     720          60 : void SAL_CALL OSingleSelectQueryComposer::setHavingClause( const OUString& filter ) throw(SQLException, RuntimeException, std::exception)
     721             : {
     722          60 :     setSingleAdditiveClause( Having, filter );
     723          60 : }
     724             : 
     725             : // XTablesSupplier
     726         154 : Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getTables(  ) throw(RuntimeException, std::exception)
     727             : {
     728         154 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
     729             : 
     730         154 :     ::osl::MutexGuard aGuard( m_aMutex );
     731         154 :     if ( !m_pTables )
     732             :     {
     733          92 :         const OSQLTables& aTables = m_aSqlIterator.getTables();
     734          92 :         ::std::vector< OUString> aNames;
     735          92 :         OSQLTables::const_iterator aEnd = aTables.end();
     736         162 :         for(OSQLTables::const_iterator aIter = aTables.begin(); aIter != aEnd;++aIter)
     737          70 :             aNames.push_back(aIter->first);
     738             : 
     739          92 :         m_pTables = new OPrivateTables(aTables,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames);
     740             :     }
     741             : 
     742         154 :     return m_pTables;
     743             : }
     744             : 
     745             : // XColumnsSupplier
     746          90 : Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns(  ) throw(RuntimeException, std::exception)
     747             : {
     748          90 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
     749          90 :     ::osl::MutexGuard aGuard( m_aMutex );
     750          90 :     if ( !!m_aCurrentColumns[SelectColumns] )
     751          20 :         return m_aCurrentColumns[SelectColumns];
     752             : 
     753         140 :     ::std::vector< OUString> aNames;
     754         140 :     ::rtl::Reference< OSQLColumns> aSelectColumns;
     755          70 :     bool bCase = true;
     756         140 :     Reference< XNameAccess> xQueryColumns;
     757          70 :     if ( m_nCommandType == CommandType::QUERY )
     758             :     {
     759           0 :         Reference<XColumnsSupplier> xSup(m_xConnectionQueries->getByName(m_sCommand),UNO_QUERY);
     760           0 :         if(xSup.is())
     761           0 :             xQueryColumns = xSup->getColumns();
     762             :     }
     763             : 
     764             :     do {
     765             : 
     766             :     try
     767             :     {
     768          70 :         SharedUNOComponent< XStatement, DisposableComponent > xStatement;
     769         140 :         SharedUNOComponent< XPreparedStatement, DisposableComponent > xPreparedStatement;
     770             : 
     771          70 :         bCase = m_xMetaData->supportsMixedCaseQuotedIdentifiers();
     772          70 :         aSelectColumns = m_aSqlIterator.getSelectColumns();
     773             : 
     774         140 :         OUStringBuffer aSQL( m_aPureSelectSQL + STR_WHERE " ( 0 = 1 )");
     775             : 
     776             :         // preserve the original WHERE clause
     777             :         // #i102234#
     778         140 :         OUString sOriginalWhereClause = getSQLPart( Where, m_aSqlIterator, false );
     779          70 :         if ( !sOriginalWhereClause.isEmpty() )
     780             :         {
     781           6 :             aSQL.append( " AND ( " + sOriginalWhereClause + " ) " );
     782             :         }
     783             : 
     784         140 :         OUString sGroupBy = getSQLPart( Group, m_aSqlIterator, true );
     785          70 :         if ( !sGroupBy.isEmpty() )
     786           0 :             aSQL.append( sGroupBy );
     787             : 
     788         140 :         OUString sSQL( aSQL.makeStringAndClear() );
     789             :         // normalize the statement so that it doesn't contain any application-level features anymore
     790         140 :         OUString sError;
     791         140 :         const boost::scoped_ptr< OSQLParseNode > pStatementTree( m_aSqlParser.parseTree( sError, sSQL, false ) );
     792             :         OSL_ENSURE( pStatementTree.get(), "OSingleSelectQueryComposer::getColumns: could not parse the column retrieval statement!" );
     793          70 :         if ( pStatementTree.get() )
     794          70 :             if ( !pStatementTree->parseNodeToExecutableStatement( sSQL, m_xConnection, m_aSqlParser, NULL ) )
     795           0 :                 break;
     796             : 
     797         140 :         Reference< XResultSetMetaData > xResultSetMeta;
     798         140 :         Reference< XResultSetMetaDataSupplier > xResMetaDataSup;
     799             :         try
     800             :         {
     801          70 :             xPreparedStatement.set( m_xConnection->prepareStatement( sSQL ), UNO_QUERY_THROW );
     802          48 :             xResMetaDataSup.set( xPreparedStatement, UNO_QUERY_THROW );
     803          48 :             xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW );
     804             :         }
     805          22 :         catch( const Exception& ) { }
     806             : 
     807             :         try
     808             :         {
     809          70 :             if ( !xResultSetMeta.is() )
     810             :             {
     811          22 :                 xStatement.reset( Reference< XStatement >( m_xConnection->createStatement(), UNO_QUERY_THROW ) );
     812          22 :                 Reference< XPropertySet > xStatementProps( xStatement, UNO_QUERY_THROW );
     813          22 :                 try { xStatementProps->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, makeAny( sal_False ) ); }
     814           0 :                 catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
     815          22 :                 xResMetaDataSup.set( xStatement->executeQuery( sSQL ), UNO_QUERY_THROW );
     816           0 :                 xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW );
     817             :             }
     818             :         }
     819          22 :         catch( const Exception& )
     820             :         {
     821             :             //@see issue http://qa.openoffice.org/issues/show_bug.cgi?id=110111
     822             :             // access returns a different order of column names when executing select * from
     823             :             // and asking the columns from the metadata.
     824          22 :             Reference< XParameters > xParameters( xPreparedStatement, UNO_QUERY_THROW );
     825           0 :             Reference< XIndexAccess > xPara = getParameters();
     826           0 :             for(sal_Int32 i = 1;i <= xPara->getCount();++i)
     827           0 :                 xParameters->setNull(i,DataType::VARCHAR);
     828           0 :             xResMetaDataSup.set(xPreparedStatement->executeQuery(), UNO_QUERY_THROW );
     829           0 :             xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW );
     830             :         }
     831             : 
     832          48 :         if ( aSelectColumns->get().empty() )
     833             :         {
     834             :             // This is a valid case. If we can syntactically parse the query, but not semantically
     835             :             // (e.g. because it is based on a table we do not know), then there will be no SelectColumns
     836           0 :             aSelectColumns = ::connectivity::parse::OParseColumn::createColumnsForResultSet( xResultSetMeta, m_xMetaData ,xQueryColumns);
     837           0 :             break;
     838             :         }
     839             : 
     840          48 :         const ::comphelper::UStringMixEqual aCaseCompare( bCase );
     841             :         typedef ::std::set< size_t > SizeTSet;
     842          96 :         SizeTSet aUsedSelectColumns;
     843          96 :         ::connectivity::parse::OParseColumn::StringMap aColumnNames;
     844             : 
     845          48 :         sal_Int32 nCount = xResultSetMeta->getColumnCount();
     846             :         OSL_ENSURE( (size_t) nCount == aSelectColumns->get().size(), "OSingleSelectQueryComposer::getColumns: inconsistent column counts, this might result in wrong columns!" );
     847         682 :         for(sal_Int32 i=1;i<=nCount;++i)
     848             :         {
     849         634 :             OUString sColumnName = xResultSetMeta->getColumnName(i);
     850         634 :             OUString sColumnLabel;
     851         634 :             if ( xQueryColumns.is() && xQueryColumns->hasByName(sColumnName) )
     852             :             {
     853           0 :                 Reference<XPropertySet> xQueryColumn(xQueryColumns->getByName(sColumnName),UNO_QUERY_THROW);
     854           0 :                 xQueryColumn->getPropertyValue(PROPERTY_LABEL) >>= sColumnLabel;
     855             :             }
     856             :             else
     857         634 :                 sColumnLabel = xResultSetMeta->getColumnLabel(i);
     858         634 :             bool bFound = false;
     859         634 :             OSQLColumns::Vector::const_iterator aFind = ::connectivity::find(aSelectColumns->get().begin(),aSelectColumns->get().end(),sColumnLabel,aCaseCompare);
     860         634 :             size_t nFoundSelectColumnPos = aFind - aSelectColumns->get().begin();
     861         634 :             if ( aFind != aSelectColumns->get().end() )
     862             :             {
     863         634 :                 if ( aUsedSelectColumns.find( nFoundSelectColumnPos ) != aUsedSelectColumns.end() )
     864             :                 {   // we found a column name which exists twice
     865             :                     // so we start after the first found
     866           0 :                     do
     867             :                     {
     868           0 :                         aFind = ::connectivity::findRealName(++aFind,aSelectColumns->get().end(),sColumnName,aCaseCompare);
     869           0 :                         nFoundSelectColumnPos = aFind - aSelectColumns->get().begin();
     870             :                     }
     871           0 :                     while   (   ( aUsedSelectColumns.find( nFoundSelectColumnPos ) != aUsedSelectColumns.end() )
     872           0 :                                 &&  ( aFind != aSelectColumns->get().end() )
     873             :                             );
     874             :                 }
     875         634 :                 if ( aFind != aSelectColumns->get().end() )
     876             :                 {
     877         634 :                     (*aFind)->getPropertyValue(PROPERTY_NAME) >>= sColumnName;
     878         634 :                     aUsedSelectColumns.insert( nFoundSelectColumnPos );
     879         634 :                     aNames.push_back(sColumnName);
     880         634 :                     bFound = true;
     881             :                 }
     882             :             }
     883             : 
     884         634 :             if ( bFound )
     885         634 :                 continue;
     886             : 
     887             :             OSQLColumns::Vector::const_iterator aRealFind = ::connectivity::findRealName(
     888           0 :                 aSelectColumns->get().begin(), aSelectColumns->get().end(), sColumnName, aCaseCompare );
     889             : 
     890           0 :             if ( i > static_cast< sal_Int32>( aSelectColumns->get().size() ) )
     891             :             {
     892           0 :                 aSelectColumns->get().push_back(
     893           0 :                     ::connectivity::parse::OParseColumn::createColumnForResultSet( xResultSetMeta, m_xMetaData, i ,aColumnNames)
     894           0 :                 );
     895             :                 OSL_ENSURE( aSelectColumns->get().size() == (size_t)i, "OSingleSelectQueryComposer::getColumns: inconsistency!" );
     896             :             }
     897           0 :             else if ( aRealFind == aSelectColumns->get().end() )
     898             :             {
     899             :                 // we can now only look if we found it under the realname propertery
     900             :                 // here we have to make the assumption that the position is correct
     901           0 :                 OSQLColumns::Vector::iterator aFind2 = aSelectColumns->get().begin() + i-1;
     902           0 :                 Reference<XPropertySet> xProp(*aFind2,UNO_QUERY);
     903           0 :                 if ( !xProp.is() || !xProp->getPropertySetInfo()->hasPropertyByName( PROPERTY_REALNAME ) )
     904           0 :                     continue;
     905             : 
     906           0 :                 ::connectivity::parse::OParseColumn* pColumn = new ::connectivity::parse::OParseColumn(xProp,bCase);
     907           0 :                 pColumn->setFunction(::comphelper::getBOOL(xProp->getPropertyValue("Function")));
     908           0 :                 pColumn->setAggregateFunction(::comphelper::getBOOL(xProp->getPropertyValue("AggregateFunction")));
     909             : 
     910           0 :                 OUString sRealName;
     911           0 :                 xProp->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
     912           0 :                 ::std::vector< OUString>::iterator aFindName;
     913           0 :                 if ( sColumnName.isEmpty() )
     914           0 :                     xProp->getPropertyValue(PROPERTY_NAME) >>= sColumnName;
     915             : 
     916           0 :                 aFindName = ::std::find_if(aNames.begin(),aNames.end(),::std::bind2nd(aCaseCompare,sColumnName));
     917           0 :                 sal_Int32 j = 0;
     918           0 :                 while ( aFindName != aNames.end() )
     919             :                 {
     920           0 :                     sColumnName += OUString::number(++j);
     921           0 :                     aFindName = ::std::find_if(aNames.begin(),aNames.end(),::std::bind2nd(aCaseCompare,sColumnName));
     922             :                 }
     923             : 
     924           0 :                 pColumn->setName(sColumnName);
     925           0 :                 pColumn->setRealName(sRealName);
     926           0 :                 pColumn->setTableName(::comphelper::getString(xProp->getPropertyValue(PROPERTY_TABLENAME)));
     927             : 
     928           0 :                 (aSelectColumns->get())[i-1] = pColumn;
     929             :             }
     930             :             else
     931           0 :                 continue;
     932             : 
     933           0 :             aUsedSelectColumns.insert( (size_t)(i - 1) );
     934           0 :             aNames.push_back( sColumnName );
     935          70 :         }
     936             :     }
     937          22 :     catch(const Exception&)
     938             :     {
     939             :     }
     940             : 
     941             :     } while ( false );
     942             : 
     943          70 :     bool bMissingSomeColumnLabels = !aNames.empty() && aNames.size() != aSelectColumns->get().size();
     944             :     SAL_WARN_IF(bMissingSomeColumnLabels, "dbaccess", "We have column labels for *some* columns but not all");
     945             :     //^^this happens in the evolution address book where we have real column names of e.g.
     946             :     //first_name, second_name and city. On parsing via
     947             :     //OSQLParseTreeIterator::appendColumns it creates some labels using those real names
     948             :     //but the evo address book gives them proper labels of First Name, Second Name and City
     949             :     //the munge means that here we have e.g. just "City" as a label because it matches
     950             : 
     951             :     //This is all a horrible mess
     952          70 :     if (bMissingSomeColumnLabels)
     953           0 :         aNames.clear();
     954             : 
     955          70 :     if ( aNames.empty() )
     956          22 :         m_aCurrentColumns[ SelectColumns ] = OPrivateColumns::createWithIntrinsicNames( aSelectColumns, bCase, *this, m_aMutex );
     957             :     else
     958          48 :         m_aCurrentColumns[ SelectColumns ] = new OPrivateColumns( aSelectColumns, bCase, *this, m_aMutex, aNames );
     959             : 
     960         160 :     return m_aCurrentColumns[SelectColumns];
     961             : }
     962             : 
     963          32 : bool OSingleSelectQueryComposer::setORCriteria(OSQLParseNode* pCondition, OSQLParseTreeIterator& _rIterator,
     964             :                                     ::std::vector< ::std::vector < PropertyValue > >& rFilters, const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter) const
     965             : {
     966             :     // Round brackets around the expression
     967          96 :     if (pCondition->count() == 3 &&
     968          32 :         SQL_ISPUNCTUATION(pCondition->getChild(0),"(") &&
     969           0 :         SQL_ISPUNCTUATION(pCondition->getChild(2),")"))
     970             :     {
     971           0 :         return setORCriteria(pCondition->getChild(1), _rIterator, rFilters, xFormatter);
     972             :     }
     973             :     // OR logic expression
     974             :     // a searchcondition can only look like this: search_condition SQL_TOKEN_OR boolean_term
     975          32 :     else if (SQL_ISRULE(pCondition,search_condition))
     976             :     {
     977          32 :         bool bResult = true;
     978          96 :         for (int i = 0; bResult && i < 3; i+=2)
     979             :         {
     980             :             // Is the first element a OR logic expression again?
     981             :             // Then descend recursively ...
     982          64 :             if (SQL_ISRULE(pCondition->getChild(i),search_condition))
     983          24 :                 bResult = setORCriteria(pCondition->getChild(i), _rIterator, rFilters, xFormatter);
     984             :             else
     985             :             {
     986          40 :                 rFilters.push_back( ::std::vector < PropertyValue >());
     987          40 :                 bResult = setANDCriteria(pCondition->getChild(i), _rIterator, rFilters[rFilters.size() - 1], xFormatter);
     988             :             }
     989             :         }
     990          32 :         return bResult;
     991             :     }
     992             :     else
     993             :     {
     994           0 :         rFilters.push_back(::std::vector < PropertyValue >());
     995           0 :         return setANDCriteria(pCondition, _rIterator, rFilters[rFilters.size() - 1], xFormatter);
     996             :     }
     997             : }
     998             : 
     999         104 : bool OSingleSelectQueryComposer::setANDCriteria( OSQLParseNode * pCondition,
    1000             :     OSQLParseTreeIterator& _rIterator, ::std::vector < PropertyValue >& rFilter, const Reference< XNumberFormatter > & xFormatter) const
    1001             : {
    1002             :     // Round brackets
    1003         104 :     if (SQL_ISRULE(pCondition,boolean_primary))
    1004             :     {
    1005             :         // this should not occur
    1006             :         SAL_WARN("dbaccess","boolean_primary in And-Criteria");
    1007           0 :         return false;
    1008             :     }
    1009             :     // The first element is an AND logical expression again
    1010         104 :     else if ( SQL_ISRULE(pCondition,boolean_term) && pCondition->count() == 3 )
    1011             :     {
    1012          64 :         return setANDCriteria(pCondition->getChild(0), _rIterator, rFilter, xFormatter) &&
    1013          64 :                setANDCriteria(pCondition->getChild(2), _rIterator, rFilter, xFormatter);
    1014             :     }
    1015          72 :     else if (SQL_ISRULE(pCondition, comparison_predicate))
    1016             :     {
    1017          72 :         return setComparsionPredicate(pCondition,_rIterator,rFilter,xFormatter);
    1018             :     }
    1019           0 :     else if (SQL_ISRULE(pCondition,like_predicate) ||
    1020           0 :              SQL_ISRULE(pCondition,test_for_null) ||
    1021           0 :              SQL_ISRULE(pCondition,in_predicate) ||
    1022           0 :              SQL_ISRULE(pCondition,all_or_any_predicate) ||
    1023           0 :              SQL_ISRULE(pCondition,between_predicate))
    1024             :     {
    1025           0 :         if (SQL_ISRULE(pCondition->getChild(0), column_ref))
    1026             :         {
    1027           0 :             PropertyValue aItem;
    1028           0 :             OUString aValue;
    1029           0 :             OUString aColumnName;
    1030             : 
    1031           0 :             pCondition->parseNodeToStr( aValue, m_xConnection, NULL );
    1032           0 :             pCondition->getChild(0)->parseNodeToStr( aColumnName, m_xConnection, NULL );
    1033             : 
    1034             :             // don't display the column name
    1035           0 :             aValue = aValue.copy(aColumnName.getLength());
    1036           0 :             aValue = aValue.trim();
    1037             : 
    1038           0 :             aItem.Name = getColumnName(pCondition->getChild(0),_rIterator);
    1039           0 :             aItem.Value <<= aValue;
    1040           0 :             aItem.Handle = 0; // just to know that this is not one the known ones
    1041           0 :             if ( SQL_ISRULE(pCondition,like_predicate) )
    1042             :             {
    1043           0 :                 if ( SQL_ISTOKEN(pCondition->getChild(1)->getChild(0),NOT) )
    1044           0 :                     aItem.Handle = SQLFilterOperator::NOT_LIKE;
    1045             :                 else
    1046           0 :                     aItem.Handle = SQLFilterOperator::LIKE;
    1047             :             }
    1048           0 :             else if (SQL_ISRULE(pCondition,test_for_null))
    1049             :             {
    1050           0 :                 if (SQL_ISTOKEN(pCondition->getChild(1)->getChild(1),NOT) )
    1051           0 :                     aItem.Handle = SQLFilterOperator::NOT_SQLNULL;
    1052             :                 else
    1053           0 :                     aItem.Handle = SQLFilterOperator::SQLNULL;
    1054             :             }
    1055           0 :             else if (SQL_ISRULE(pCondition,in_predicate))
    1056             :             {
    1057             :                 SAL_WARN("dbaccess", "OSingleSelectQueryComposer::setANDCriteria: in_predicate not implemented!" );
    1058             :             }
    1059           0 :             else if (SQL_ISRULE(pCondition,all_or_any_predicate))
    1060             :             {
    1061             :                 SAL_WARN("dbaccess", "OSingleSelectQueryComposer::setANDCriteria: all_or_any_predicate not implemented!" );
    1062             :             }
    1063           0 :             else if (SQL_ISRULE(pCondition,between_predicate))
    1064             :             {
    1065             :                 SAL_WARN("dbaccess", "OSingleSelectQueryComposer::setANDCriteria: between_predicate not implemented!" );
    1066             :             }
    1067             : 
    1068           0 :             rFilter.push_back(aItem);
    1069             :         }
    1070             :         else
    1071           0 :             return false;
    1072             :     }
    1073           0 :     else if (SQL_ISRULE(pCondition,existence_test) ||
    1074           0 :              SQL_ISRULE(pCondition,unique_test))
    1075             :     {
    1076             :         // this couldn't be handled here, too complex
    1077             :         // as we need a field name
    1078           0 :         return false;
    1079             :     }
    1080             :     else
    1081           0 :         return false;
    1082             : 
    1083           0 :     return true;
    1084             : }
    1085             : 
    1086          72 : sal_Int32 OSingleSelectQueryComposer::getPredicateType(OSQLParseNode * _pPredicate) const
    1087             : {
    1088          72 :     sal_Int32 nPredicate = SQLFilterOperator::EQUAL;
    1089          72 :     switch (_pPredicate->getNodeType())
    1090             :     {
    1091             :         case SQL_NODE_EQUAL:
    1092          72 :             nPredicate = SQLFilterOperator::EQUAL;
    1093          72 :             break;
    1094             :         case SQL_NODE_NOTEQUAL:
    1095           0 :             nPredicate = SQLFilterOperator::NOT_EQUAL;
    1096           0 :             break;
    1097             :         case SQL_NODE_LESS:
    1098           0 :             nPredicate = SQLFilterOperator::LESS;
    1099           0 :             break;
    1100             :         case SQL_NODE_LESSEQ:
    1101           0 :             nPredicate = SQLFilterOperator::LESS_EQUAL;
    1102           0 :             break;
    1103             :         case SQL_NODE_GREAT:
    1104           0 :             nPredicate = SQLFilterOperator::GREATER;
    1105           0 :             break;
    1106             :         case SQL_NODE_GREATEQ:
    1107           0 :             nPredicate = SQLFilterOperator::GREATER_EQUAL;
    1108           0 :             break;
    1109             :         default:
    1110             :             SAL_WARN("dbaccess","Wrong NodeType!");
    1111             :     }
    1112          72 :     return nPredicate;
    1113             : }
    1114             : 
    1115          72 : bool OSingleSelectQueryComposer::setComparsionPredicate(OSQLParseNode * pCondition, OSQLParseTreeIterator& _rIterator,
    1116             :                                             ::std::vector < PropertyValue >& rFilter, const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter) const
    1117             : {
    1118             :     OSL_ENSURE(SQL_ISRULE(pCondition, comparison_predicate),"setComparsionPredicate: pCondition ist kein ComparsionPredicate");
    1119         144 :     if (SQL_ISRULE(pCondition->getChild(0), column_ref) ||
    1120           0 :         SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref))
    1121             :     {
    1122          72 :         PropertyValue aItem;
    1123         144 :         OUString aValue;
    1124             :         sal_uInt32 nPos;
    1125          72 :         if (SQL_ISRULE(pCondition->getChild(0), column_ref))
    1126             :         {
    1127          72 :             nPos = 0;
    1128          72 :             sal_uInt32 i=1;
    1129             : 
    1130          72 :             aItem.Handle = getPredicateType(pCondition->getChild(i));
    1131             :             // don't display the equal
    1132          72 :             if (pCondition->getChild(i)->getNodeType() == SQL_NODE_EQUAL)
    1133          72 :                 i++;
    1134             : 
    1135             :             // go forward
    1136         144 :             for (;i < pCondition->count();i++)
    1137             :                 pCondition->getChild(i)->parseNodeToPredicateStr(
    1138          72 :                     aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>(m_sDecimalSep.toChar() ) );
    1139             :         }
    1140           0 :         else if (SQL_ISRULE(pCondition->getChild(pCondition->count()-1), column_ref))
    1141             :         {
    1142           0 :             nPos = pCondition->count()-1;
    1143             : 
    1144           0 :             sal_Int32 i = pCondition->count() - 2;
    1145           0 :             switch (pCondition->getChild(i)->getNodeType())
    1146             :             {
    1147             :                 case SQL_NODE_EQUAL:
    1148             :                     // don't display the equal
    1149           0 :                     i--;
    1150           0 :                     aItem.Handle = SQLFilterOperator::EQUAL;
    1151           0 :                     break;
    1152             :                 case SQL_NODE_NOTEQUAL:
    1153           0 :                     i--;
    1154           0 :                     aItem.Handle = SQLFilterOperator::NOT_EQUAL;
    1155           0 :                     break;
    1156             :                 case SQL_NODE_LESS:
    1157             :                     // take the opposite as we change the order
    1158           0 :                     i--;
    1159           0 :                     aValue = ">=";
    1160           0 :                     aItem.Handle = SQLFilterOperator::GREATER_EQUAL;
    1161           0 :                     break;
    1162             :                 case SQL_NODE_LESSEQ:
    1163             :                     // take the opposite as we change the order
    1164           0 :                     i--;
    1165           0 :                     aValue = ">";
    1166           0 :                     aItem.Handle = SQLFilterOperator::GREATER;
    1167           0 :                     break;
    1168             :                 case SQL_NODE_GREAT:
    1169             :                     // take the opposite as we change the order
    1170           0 :                     i--;
    1171           0 :                     aValue = "<=";
    1172           0 :                     aItem.Handle = SQLFilterOperator::LESS_EQUAL;
    1173           0 :                     break;
    1174             :                 case SQL_NODE_GREATEQ:
    1175             :                     // take the opposite as we change the order
    1176           0 :                     i--;
    1177           0 :                     aValue = "<";
    1178           0 :                     aItem.Handle = SQLFilterOperator::LESS;
    1179           0 :                     break;
    1180             :                 default:
    1181           0 :                     break;
    1182             :             }
    1183             : 
    1184             :             // go backward
    1185           0 :             for (; i >= 0; i--)
    1186             :                 pCondition->getChild(i)->parseNodeToPredicateStr(
    1187           0 :                     aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) );
    1188             :         }
    1189             :         else
    1190           0 :             return false;
    1191             : 
    1192          72 :         aItem.Name = getColumnName(pCondition->getChild(nPos),_rIterator);
    1193          72 :         aItem.Value <<= aValue;
    1194         144 :         rFilter.push_back(aItem);
    1195             :     }
    1196           0 :     else if (SQL_ISRULE(pCondition->getChild(0), set_fct_spec ) ||
    1197           0 :              SQL_ISRULE(pCondition->getChild(0), general_set_fct))
    1198             :     {
    1199           0 :         PropertyValue aItem;
    1200           0 :         OUString aValue;
    1201           0 :         OUString aColumnName;
    1202             : 
    1203           0 :         pCondition->getChild(2)->parseNodeToPredicateStr(aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) );
    1204           0 :         pCondition->getChild(0)->parseNodeToPredicateStr( aColumnName, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep .toChar() ) );
    1205             : 
    1206           0 :         aItem.Name = getColumnName(pCondition->getChild(0),_rIterator);
    1207           0 :         aItem.Value <<= aValue;
    1208           0 :         aItem.Handle = getPredicateType(pCondition->getChild(1));
    1209           0 :         rFilter.push_back(aItem);
    1210             :     }
    1211             :     else // Can only be an expression
    1212             :     {
    1213           0 :         PropertyValue aItem;
    1214           0 :         OUString aName, aValue;
    1215             : 
    1216           0 :         OSQLParseNode *pLhs = pCondition->getChild(0);
    1217           0 :         OSQLParseNode *pRhs = pCondition->getChild(2);
    1218             : 
    1219             :         // Field names
    1220             :         sal_uInt16 i;
    1221           0 :         for (i=0;i< pLhs->count();i++)
    1222           0 :              pLhs->getChild(i)->parseNodeToPredicateStr( aName, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) );
    1223             : 
    1224             :         // Criterion
    1225           0 :         aItem.Handle = getPredicateType(pCondition->getChild(1));
    1226           0 :         aValue       = pCondition->getChild(1)->getTokenValue();
    1227           0 :         for(i=0;i< pRhs->count();i++)
    1228           0 :             pRhs->getChild(i)->parseNodeToPredicateStr(aValue, m_xConnection, xFormatter, m_aLocale, static_cast<sal_Char>( m_sDecimalSep.toChar() ) );
    1229             : 
    1230           0 :         aItem.Name = aName;
    1231           0 :         aItem.Value <<= aValue;
    1232           0 :         rFilter.push_back(aItem);
    1233             :     }
    1234          72 :     return true;
    1235             : }
    1236             : 
    1237             : // Functions for analysing SQL
    1238          72 : OUString OSingleSelectQueryComposer::getColumnName( ::connectivity::OSQLParseNode* pColumnRef, OSQLParseTreeIterator& _rIterator ) const
    1239             : {
    1240          72 :     OUString aTableRange, aColumnName;
    1241          72 :     _rIterator.getColumnRange(pColumnRef,aColumnName,aTableRange);
    1242          72 :     return aColumnName;
    1243             : }
    1244             : 
    1245          47 : OUString SAL_CALL OSingleSelectQueryComposer::getFilter(  ) throw(RuntimeException, std::exception)
    1246             : {
    1247          47 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
    1248          47 :     ::osl::MutexGuard aGuard( m_aMutex );
    1249          47 :     return getSQLPart(Where,m_aAdditiveIterator,false);
    1250             : }
    1251             : 
    1252          19 : OUString SAL_CALL OSingleSelectQueryComposer::getOrder(  ) throw(RuntimeException, std::exception)
    1253             : {
    1254          19 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
    1255          19 :     ::osl::MutexGuard aGuard( m_aMutex );
    1256          19 :     return getSQLPart(Order,m_aAdditiveIterator,false);
    1257             : }
    1258             : 
    1259           6 : OUString SAL_CALL OSingleSelectQueryComposer::getGroup(  ) throw (RuntimeException, std::exception)
    1260             : {
    1261           6 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
    1262           6 :     ::osl::MutexGuard aGuard( m_aMutex );
    1263           6 :     return getSQLPart(Group,m_aAdditiveIterator,false);
    1264             : }
    1265             : 
    1266          21 : OUString OSingleSelectQueryComposer::getHavingClause() throw (RuntimeException, std::exception)
    1267             : {
    1268          21 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
    1269          21 :     ::osl::MutexGuard aGuard( m_aMutex );
    1270          21 :     return getSQLPart(Having,m_aAdditiveIterator,false);
    1271             : }
    1272             : 
    1273           0 : OUString OSingleSelectQueryComposer::getTableAlias(const Reference< XPropertySet >& column) const
    1274             : {
    1275           0 :     OUString sReturn;
    1276           0 :     if(m_pTables && m_pTables->getCount() > 1)
    1277             :     {
    1278           0 :         OUString aCatalog,aSchema,aTable,aComposedName,aColumnName;
    1279           0 :         if(column->getPropertySetInfo()->hasPropertyByName(PROPERTY_CATALOGNAME))
    1280           0 :             column->getPropertyValue(PROPERTY_CATALOGNAME)  >>= aCatalog;
    1281           0 :         if(column->getPropertySetInfo()->hasPropertyByName(PROPERTY_SCHEMANAME))
    1282           0 :             column->getPropertyValue(PROPERTY_SCHEMANAME)   >>= aSchema;
    1283           0 :         if(column->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME))
    1284           0 :             column->getPropertyValue(PROPERTY_TABLENAME)    >>= aTable;
    1285           0 :         column->getPropertyValue(PROPERTY_NAME)         >>= aColumnName;
    1286             : 
    1287           0 :         Sequence< OUString> aNames(m_pTables->getElementNames());
    1288           0 :         const OUString* pBegin     = aNames.getConstArray();
    1289           0 :         const OUString* const pEnd = pBegin + aNames.getLength();
    1290             : 
    1291           0 :         if(aTable.isEmpty())
    1292             :         { // we haven't found a table name, now we must search every table for this column
    1293           0 :             for(;pBegin != pEnd;++pBegin)
    1294             :             {
    1295           0 :                 Reference<XColumnsSupplier> xColumnsSupp;
    1296           0 :                 m_pTables->getByName(*pBegin) >>= xColumnsSupp;
    1297             : 
    1298           0 :                 if(xColumnsSupp.is() && xColumnsSupp->getColumns()->hasByName(aColumnName))
    1299             :                 {
    1300           0 :                     aTable = *pBegin;
    1301           0 :                     break;
    1302             :                 }
    1303           0 :             }
    1304             :         }
    1305             :         else
    1306             :         {
    1307           0 :             aComposedName = ::dbtools::composeTableName( m_xMetaData, aCatalog, aSchema, aTable, false, ::dbtools::eInDataManipulation );
    1308             : 
    1309             :             // Is this the right case for the table name?
    1310             :             // Else, look for it with different case, if applicable.
    1311             : 
    1312           0 :             if(!m_pTables->hasByName(aComposedName))
    1313             :             {
    1314           0 :                 ::comphelper::UStringMixLess aTmp(m_aAdditiveIterator.getTables().key_comp());
    1315           0 :                 ::comphelper::UStringMixEqual aComp(static_cast< ::comphelper::UStringMixLess*>(&aTmp)->isCaseSensitive());
    1316           0 :                 for(;pBegin != pEnd;++pBegin)
    1317             :                 {
    1318           0 :                     Reference<XPropertySet> xTableProp;
    1319           0 :                     m_pTables->getByName(*pBegin) >>= xTableProp;
    1320             :                     OSL_ENSURE(xTableProp.is(),"Table isn't a propertyset!");
    1321           0 :                     if(xTableProp.is())
    1322             :                     {
    1323           0 :                         OUString aCatalog2,aSchema2,aTable2;
    1324           0 :                         xTableProp->getPropertyValue(PROPERTY_CATALOGNAME)  >>= aCatalog2;
    1325           0 :                         xTableProp->getPropertyValue(PROPERTY_SCHEMANAME)   >>= aSchema2;
    1326           0 :                         xTableProp->getPropertyValue(PROPERTY_NAME)         >>= aTable2;
    1327           0 :                         if(aComp(aCatalog,aCatalog2) && aComp(aSchema,aSchema2) && aComp(aTable,aTable2))
    1328             :                         {
    1329           0 :                             aCatalog    = aCatalog2;
    1330           0 :                             aSchema     = aSchema2;
    1331           0 :                             aTable      = aTable2;
    1332           0 :                             break;
    1333           0 :                         }
    1334             :                     }
    1335           0 :                 }
    1336             :             }
    1337             :         }
    1338           0 :         if(pBegin != pEnd)
    1339             :         {
    1340           0 :             sReturn = ::dbtools::composeTableName( m_xMetaData, aCatalog, aSchema, aTable, true, ::dbtools::eInDataManipulation ) + ".";
    1341           0 :         }
    1342             :     }
    1343           0 :     return sReturn;
    1344             : }
    1345             : 
    1346          86 : Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getParameters(  ) throw(RuntimeException, std::exception)
    1347             : {
    1348             :     // now set the Parameters
    1349          86 :     if ( !m_aCurrentColumns[ParameterColumns] )
    1350             :     {
    1351          76 :         ::rtl::Reference< OSQLColumns> aCols = m_aSqlIterator.getParameters();
    1352         152 :         ::std::vector< OUString> aNames;
    1353          76 :         OSQLColumns::Vector::const_iterator aEnd = aCols->get().end();
    1354          84 :         for(OSQLColumns::Vector::const_iterator aIter = aCols->get().begin(); aIter != aEnd;++aIter)
    1355           8 :             aNames.push_back(getString((*aIter)->getPropertyValue(PROPERTY_NAME)));
    1356         152 :         m_aCurrentColumns[ParameterColumns] = new OPrivateColumns(aCols,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames,true);
    1357             :     }
    1358             : 
    1359          86 :     return m_aCurrentColumns[ParameterColumns];
    1360             : }
    1361             : 
    1362          70 : void OSingleSelectQueryComposer::clearColumns( const EColumnType _eType )
    1363             : {
    1364          70 :     OPrivateColumns* pColumns = m_aCurrentColumns[ _eType ];
    1365          70 :     if ( pColumns != NULL )
    1366             :     {
    1367           0 :         pColumns->disposing();
    1368           0 :         m_aColumnsCollection.push_back( pColumns );
    1369           0 :         m_aCurrentColumns[ _eType ] = NULL;
    1370             :     }
    1371          70 : }
    1372             : 
    1373         204 : void OSingleSelectQueryComposer::clearCurrentCollections()
    1374             : {
    1375         204 :     ::std::vector<OPrivateColumns*>::iterator aIter = m_aCurrentColumns.begin();
    1376         204 :     ::std::vector<OPrivateColumns*>::iterator aEnd = m_aCurrentColumns.end();
    1377        1020 :     for (;aIter != aEnd;++aIter)
    1378             :     {
    1379         816 :         if ( *aIter )
    1380             :         {
    1381         152 :             (*aIter)->disposing();
    1382         152 :             m_aColumnsCollection.push_back(*aIter);
    1383         152 :             *aIter = NULL;
    1384             :         }
    1385             :     }
    1386             : 
    1387         204 :     if(m_pTables)
    1388             :     {
    1389          92 :         m_pTables->disposing();
    1390          92 :         m_aTablesCollection.push_back(m_pTables);
    1391          92 :         m_pTables = NULL;
    1392             :     }
    1393         204 : }
    1394             : 
    1395           6 : Reference< XIndexAccess > OSingleSelectQueryComposer::setCurrentColumns( EColumnType _eType,
    1396             :     const ::rtl::Reference< OSQLColumns >& _rCols )
    1397             : {
    1398           6 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
    1399             : 
    1400           6 :     ::osl::MutexGuard aGuard( m_aMutex );
    1401             :     // now set the group columns
    1402           6 :     if ( !m_aCurrentColumns[_eType] )
    1403             :     {
    1404           6 :         ::std::vector< OUString> aNames;
    1405           6 :         OSQLColumns::Vector::const_iterator aEnd = _rCols->get().end();
    1406          12 :         for(OSQLColumns::Vector::const_iterator aIter = _rCols->get().begin(); aIter != aEnd;++aIter)
    1407           6 :             aNames.push_back(getString((*aIter)->getPropertyValue(PROPERTY_NAME)));
    1408           6 :         m_aCurrentColumns[_eType] = new OPrivateColumns(_rCols,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames,true);
    1409             :     }
    1410             : 
    1411           6 :     return m_aCurrentColumns[_eType];
    1412             : }
    1413             : 
    1414           2 : Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getGroupColumns(  ) throw(RuntimeException, std::exception)
    1415             : {
    1416           2 :     return setCurrentColumns( GroupByColumns, m_aAdditiveIterator.getGroupColumns() );
    1417             : }
    1418             : 
    1419           4 : Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getOrderColumns(  ) throw(RuntimeException, std::exception)
    1420             : {
    1421           4 :     return setCurrentColumns( OrderColumns, m_aAdditiveIterator.getOrderColumns() );
    1422             : }
    1423             : 
    1424          48 : OUString SAL_CALL OSingleSelectQueryComposer::getQueryWithSubstitution(  ) throw (SQLException, RuntimeException, std::exception)
    1425             : {
    1426          48 :     ::osl::MutexGuard aGuard( m_aMutex );
    1427          48 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
    1428             : 
    1429          48 :     OUString sSqlStatement( getQuery() );
    1430             : 
    1431          48 :     const OSQLParseNode* pStatementNode = m_aSqlIterator.getParseTree();
    1432          48 :     if ( pStatementNode )
    1433             :     {
    1434          48 :         SQLException aError;
    1435          48 :         if ( !pStatementNode->parseNodeToExecutableStatement( sSqlStatement, m_xConnection, m_aSqlParser, &aError ) )
    1436           0 :             throw SQLException( aError );
    1437             :     }
    1438             : 
    1439          48 :     return sSqlStatement;
    1440             : }
    1441             : 
    1442        1723 : OUString OSingleSelectQueryComposer::getStatementPart( TGetParseNode& _aGetFunctor, OSQLParseTreeIterator& _rIterator )
    1443             : {
    1444        1723 :     OUString sResult;
    1445             : 
    1446        1723 :     const OSQLParseNode* pNode = _aGetFunctor( &_rIterator );
    1447        1723 :     if ( pNode )
    1448         413 :         pNode->parseNodeToStr( sResult, m_xConnection );
    1449             : 
    1450        1723 :     return sResult;
    1451             : }
    1452             : 
    1453             : namespace
    1454             : {
    1455          72 :     OUString lcl_getDecomposedColumnName(const OUString& rComposedName, const OUString& rQuoteString)
    1456             :     {
    1457          72 :         const sal_Int32 nQuoteLength = rQuoteString.getLength();
    1458          72 :         OUString sName = rComposedName.trim();
    1459         144 :         OUString sColumnName;
    1460          72 :         sal_Int32 nPos, nRPos = 0;
    1461             : 
    1462             :         for (;;)
    1463             :         {
    1464          72 :             nPos = sName.indexOf( rQuoteString, nRPos );
    1465          72 :             if ( nPos >= 0 )
    1466             :             {
    1467           0 :                 nRPos = sName.indexOf( rQuoteString, nPos + nQuoteLength );
    1468           0 :                 if ( nRPos > nPos )
    1469             :                 {
    1470           0 :                     if ( nRPos + nQuoteLength < sName.getLength() )
    1471             :                     {
    1472           0 :                         nRPos += nQuoteLength; // -1 + 1 skip dot
    1473             :                     }
    1474             :                     else
    1475             :                     {
    1476           0 :                         sColumnName = sName.copy( nPos + nQuoteLength, nRPos - nPos - nQuoteLength );
    1477           0 :                         break;
    1478             :                     }
    1479             :                 }
    1480             :                 else
    1481           0 :                     break;
    1482             :             }
    1483             :             else
    1484          72 :                 break;
    1485             :         }
    1486         144 :         return sColumnName.isEmpty() ? rComposedName : sColumnName;
    1487             :     }
    1488             : 
    1489           8 :     OUString lcl_getCondition(const Sequence< Sequence< PropertyValue > >& filter,
    1490             :         const OPredicateInputController& i_aPredicateInputController,
    1491             :         const Reference< XNameAccess >& i_xSelectColumns,
    1492             :         const OUString& rQuoteString)
    1493             :     {
    1494           8 :         OUStringBuffer sRet;
    1495           8 :         const Sequence< PropertyValue >* pOrIter = filter.getConstArray();
    1496           8 :         const Sequence< PropertyValue >* pOrEnd = pOrIter + filter.getLength();
    1497          56 :         while ( pOrIter != pOrEnd )
    1498             :         {
    1499          40 :             if ( pOrIter->getLength() )
    1500             :             {
    1501          40 :                 sRet.append(L_BRACKET);
    1502          40 :                 const PropertyValue* pAndIter = pOrIter->getConstArray();
    1503          40 :                 const PropertyValue* pAndEnd = pAndIter + pOrIter->getLength();
    1504         152 :                 while ( pAndIter != pAndEnd )
    1505             :                 {
    1506          72 :                     sRet.append(pAndIter->Name);
    1507          72 :                     OUString sValue;
    1508          72 :                     pAndIter->Value >>= sValue;
    1509         144 :                     const OUString sColumnName = lcl_getDecomposedColumnName( pAndIter->Name, rQuoteString );
    1510          72 :                     if ( i_xSelectColumns.is() && i_xSelectColumns->hasByName(sColumnName) )
    1511             :                     {
    1512          72 :                         Reference<XPropertySet> xColumn(i_xSelectColumns->getByName(sColumnName),UNO_QUERY);
    1513          72 :                         sValue = i_aPredicateInputController.getPredicateValue(sValue,xColumn,true);
    1514             :                     }
    1515             :                     else
    1516             :                     {
    1517           0 :                         sValue = i_aPredicateInputController.getPredicateValue(pAndIter->Name,sValue,true);
    1518             :                     }
    1519          72 :                     lcl_addFilterCriteria_throw(pAndIter->Handle,sValue,sRet);
    1520          72 :                     ++pAndIter;
    1521          72 :                     if ( pAndIter != pAndEnd )
    1522          32 :                         sRet.append(STR_AND);
    1523          72 :                 }
    1524          40 :                 sRet.append(R_BRACKET);
    1525             :             }
    1526          40 :             ++pOrIter;
    1527          40 :             if ( pOrIter != pOrEnd && !sRet.isEmpty() )
    1528          32 :                 sRet.append(STR_OR);
    1529             :         }
    1530           8 :         return sRet.makeStringAndClear();
    1531             :     }
    1532             : }
    1533             : 
    1534           4 : void SAL_CALL OSingleSelectQueryComposer::setStructuredFilter( const Sequence< Sequence< PropertyValue > >& filter ) throw (SQLException, ::com::sun::star::lang::IllegalArgumentException, RuntimeException, std::exception)
    1535             : {
    1536           4 :     OPredicateInputController aPredicateInput(m_aContext, m_xConnection, &m_aParseContext);
    1537           4 :     setFilter(lcl_getCondition(filter, aPredicateInput, getColumns(), m_xMetaData->getIdentifierQuoteString()));
    1538           4 : }
    1539             : 
    1540           4 : void SAL_CALL OSingleSelectQueryComposer::setStructuredHavingClause( const Sequence< Sequence< PropertyValue > >& filter ) throw (SQLException, RuntimeException, std::exception)
    1541             : {
    1542           4 :     OPredicateInputController aPredicateInput(m_aContext, m_xConnection);
    1543           4 :     setHavingClause(lcl_getCondition(filter, aPredicateInput, getColumns(), m_xMetaData->getIdentifierQuoteString()));
    1544           4 : }
    1545             : 
    1546          14 : void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropertySet >& column, bool andCriteria ,::std::mem_fun1_t<bool,OSingleSelectQueryComposer,const OUString& >& _aSetFunctor,sal_Int32 filterOperator)
    1547             : {
    1548             :     try
    1549             :     {
    1550          14 :         ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
    1551             : 
    1552          46 :         if ( !column.is()
    1553          34 :              || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_VALUE)
    1554          24 :              || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME)
    1555          52 :              || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_TYPE))
    1556           4 :             throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,Any() );
    1557             : 
    1558          10 :         sal_Int32 nType = 0;
    1559          10 :         column->getPropertyValue(PROPERTY_TYPE) >>= nType;
    1560          10 :         sal_Int32 nSearchable = dbtools::getSearchColumnFlag(m_xConnection,nType);
    1561          10 :         if(nSearchable == ColumnSearch::NONE)
    1562           0 :             throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_SEARCHABLE),*this,SQLSTATE_GENERAL,1000,Any() );
    1563             : 
    1564          10 :         ::osl::MutexGuard aGuard( m_aMutex );
    1565             : 
    1566          20 :         OUString aName;
    1567          10 :         column->getPropertyValue(PROPERTY_NAME) >>= aName;
    1568             : 
    1569          20 :         Any aValue;
    1570          14 :         column->getPropertyValue(PROPERTY_VALUE) >>= aValue;
    1571             : 
    1572          12 :         OUStringBuffer aSQL;
    1573          12 :         const OUString aQuote    = m_xMetaData->getIdentifierQuoteString();
    1574           6 :         getColumns();
    1575             : 
    1576             :         // TODO: if this is called for HAVING, check that the column is a GROUP BY column
    1577             :         //       or that it is an aggregate function
    1578             : 
    1579           6 :         if ( m_aCurrentColumns[SelectColumns] && m_aCurrentColumns[SelectColumns]->hasByName(aName) )
    1580             :         {
    1581           6 :             Reference<XPropertySet> xColumn;
    1582           6 :             m_aCurrentColumns[SelectColumns]->getByName(aName) >>= xColumn;
    1583             :             OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME),"Property REALNAME not available!");
    1584             :             OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!");
    1585             :             OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName("AggregateFunction"),"Property AggregateFunction not available!");
    1586             : 
    1587          12 :             OUString sRealName,sTableName;
    1588           6 :             xColumn->getPropertyValue(PROPERTY_REALNAME)    >>= sRealName;
    1589           6 :             xColumn->getPropertyValue(PROPERTY_TABLENAME)   >>= sTableName;
    1590           6 :             if(sTableName.indexOf('.',0) != -1)
    1591             :             {
    1592           0 :                 OUString aCatlog,aSchema,aTable;
    1593           0 :                 ::dbtools::qualifiedNameComponents(m_xMetaData,sTableName,aCatlog,aSchema,aTable,::dbtools::eInDataManipulation);
    1594           0 :                 sTableName = ::dbtools::composeTableName( m_xMetaData, aCatlog, aSchema, aTable, true, ::dbtools::eInDataManipulation );
    1595             :             }
    1596             :             else
    1597           6 :                 sTableName = ::dbtools::quoteName(aQuote,sTableName);
    1598             : 
    1599           6 :             if ( !::comphelper::getBOOL(xColumn->getPropertyValue("Function")) )
    1600             :             {
    1601           6 :                 aSQL =  sTableName + "." + ::dbtools::quoteName( aQuote, sRealName );
    1602             :             }
    1603             :             else
    1604           6 :                 aSQL = sRealName;
    1605             :         }
    1606             :         else
    1607             :         {
    1608           0 :             aSQL = getTableAlias( column ) + ::dbtools::quoteName( aQuote, aName );
    1609             :         }
    1610             : 
    1611           6 :         if ( aValue.hasValue() )
    1612             :         {
    1613           6 :             if(  !m_xTypeConverter.is() )
    1614           2 :                 m_xTypeConverter.set( Converter::create(m_aContext) );
    1615             :             OSL_ENSURE(m_xTypeConverter.is(),"NO typeconverter!");
    1616             : 
    1617           6 :             if ( nType != DataType::BOOLEAN && DataType::BIT != nType )
    1618             :             {
    1619           6 :                 OUString sEmpty;
    1620           6 :                 lcl_addFilterCriteria_throw(filterOperator,sEmpty,aSQL);
    1621             :             }
    1622             : 
    1623           6 :             switch(nType)
    1624             :             {
    1625             :             case DataType::VARCHAR:
    1626             :             case DataType::CHAR:
    1627             :             case DataType::LONGVARCHAR:
    1628           6 :                 aSQL.append( DBTypeConversion::toSQLString( nType, aValue, true, m_xTypeConverter ) );
    1629           6 :                 break;
    1630             :             case DataType::CLOB:
    1631             :                 {
    1632           0 :                     Reference< XClob > xClob(aValue,UNO_QUERY);
    1633           0 :                     if ( xClob.is() )
    1634             :                     {
    1635           0 :                         const ::sal_Int64 nLength = xClob->length();
    1636           0 :                         if ( sal_Int64(nLength + aSQL.getLength() + STR_LIKE.getLength() ) < sal_Int64(SAL_MAX_INT32) )
    1637             :                         {
    1638           0 :                             aSQL.append("'" + xClob->getSubString(1,(sal_Int32)nLength) + "'");
    1639             :                         }
    1640             :                     }
    1641             :                     else
    1642             :                     {
    1643           0 :                         aSQL.append( DBTypeConversion::toSQLString( nType, aValue, true, m_xTypeConverter ) );
    1644           0 :                     }
    1645             :                 }
    1646           0 :                 break;
    1647             :             case DataType::VARBINARY:
    1648             :             case DataType::BINARY:
    1649             :             case DataType::LONGVARBINARY:
    1650             :                 {
    1651           0 :                     Sequence<sal_Int8> aSeq;
    1652           0 :                     if(aValue >>= aSeq)
    1653             :                     {
    1654           0 :                         if(nSearchable == ColumnSearch::CHAR)
    1655             :                         {
    1656           0 :                             aSQL.append( "\'" );
    1657             :                         }
    1658           0 :                         aSQL.appendAscii( "0x" );
    1659           0 :                         const sal_Int8* pBegin  = aSeq.getConstArray();
    1660           0 :                         const sal_Int8* pEnd    = pBegin + aSeq.getLength();
    1661           0 :                         for(;pBegin != pEnd;++pBegin)
    1662             :                         {
    1663           0 :                             aSQL.append( (sal_Int32)*pBegin, 16 ).getStr();
    1664             :                         }
    1665           0 :                         if(nSearchable == ColumnSearch::CHAR)
    1666           0 :                             aSQL.append( "\'" );
    1667             :                     }
    1668             :                     else
    1669           0 :                         throw SQLException(DBACORE_RESSTRING(RID_STR_NOT_SEQUENCE_INT8),*this,SQLSTATE_GENERAL,1000,Any() );
    1670             :                 }
    1671           0 :                 break;
    1672             :             case DataType::BIT:
    1673             :             case DataType::BOOLEAN:
    1674             :                 {
    1675           0 :                     bool bValue = false;
    1676           0 :                     m_xTypeConverter->convertToSimpleType(aValue, TypeClass_BOOLEAN) >>= bValue;
    1677             : 
    1678           0 :                     OUString sColumnExp = aSQL.makeStringAndClear();
    1679           0 :                     getBooleanComparisonPredicate( sColumnExp, bValue, m_nBoolCompareMode, aSQL );
    1680             :                 }
    1681           0 :                 break;
    1682             :             default:
    1683           0 :                 aSQL.append( DBTypeConversion::toSQLString( nType, aValue, true, m_xTypeConverter ) );
    1684           0 :                 break;
    1685             :             }
    1686             :         }
    1687             :         else
    1688             :         {
    1689           0 :             sal_Int32 nFilterOp = filterOperator;
    1690           0 :             if ( filterOperator != SQLFilterOperator::SQLNULL && filterOperator != SQLFilterOperator::NOT_SQLNULL )
    1691           0 :                 nFilterOp = SQLFilterOperator::SQLNULL;
    1692           0 :             OUString sEmpty;
    1693           0 :             lcl_addFilterCriteria_throw(nFilterOp,sEmpty,aSQL);
    1694             :         }
    1695             : 
    1696             :         // Attach filter
    1697             :         // Construct SELECT without WHERE and ORDER BY
    1698           6 :         OUString sFilter = getFilter();
    1699             : 
    1700           6 :         if ( !sFilter.isEmpty() && !aSQL.isEmpty() )
    1701             :         {
    1702           6 :             OUString sTemp(L_BRACKET + sFilter + R_BRACKET);
    1703           6 :             sTemp += andCriteria ? OUString(STR_AND) : OUString(STR_OR);
    1704           6 :             sFilter = sTemp;
    1705             :         }
    1706           6 :         sFilter += aSQL.makeStringAndClear();
    1707             : 
    1708             :         // add the filter and the sort order
    1709          16 :         _aSetFunctor(this,sFilter);
    1710             :     }
    1711           0 :     catch (css::lang::WrappedTargetException & e)
    1712             :     {
    1713           0 :         if (e.TargetException.isExtractableTo(
    1714           0 :                 cppu::UnoType<css::sdbc::SQLException>::get()))
    1715             :         {
    1716           0 :             cppu::throwException(e.TargetException);
    1717             :         }
    1718             :         else
    1719             :         {
    1720           0 :             throw;
    1721             :         }
    1722             :     }
    1723           6 : }
    1724             : 
    1725           8 : Sequence< Sequence< PropertyValue > > OSingleSelectQueryComposer::getStructuredCondition( TGetParseNode& _aGetFunctor )
    1726             : {
    1727           8 :     ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
    1728             : 
    1729           8 :     MutexGuard aGuard(m_aMutex);
    1730             : 
    1731           8 :     Sequence< Sequence< PropertyValue > > aFilterSeq;
    1732          16 :     OUString sFilter = getStatementPart( _aGetFunctor, m_aAdditiveIterator );
    1733             : 
    1734           8 :     if ( !sFilter.isEmpty() )
    1735             :     {
    1736           8 :         OUString aSql(m_aPureSelectSQL + STR_WHERE + sFilter);
    1737             :         // build a temporary parse node
    1738           8 :         const OSQLParseNode* pTempNode = m_aAdditiveIterator.getParseTree();
    1739             : 
    1740          16 :         OUString aErrorMsg;
    1741          16 :         boost::scoped_ptr<OSQLParseNode> pSqlParseNode( m_aSqlParser.parseTree(aErrorMsg,aSql));
    1742           8 :         if ( pSqlParseNode.get() )
    1743             :         {
    1744           8 :             m_aAdditiveIterator.setParseTree(pSqlParseNode.get());
    1745             :             // normalize the filter
    1746           8 :             OSQLParseNode* pWhereNode = const_cast<OSQLParseNode*>(m_aAdditiveIterator.getWhereTree());
    1747             : 
    1748           8 :             OSQLParseNode* pCondition = pWhereNode->getChild(1);
    1749             :         #if OSL_DEBUG_LEVEL > 0
    1750             :             OUString sCondition;
    1751             :             pCondition->parseNodeToStr( sCondition, m_xConnection );
    1752             :         #endif
    1753           8 :             OSQLParseNode::negateSearchCondition(pCondition);
    1754             : 
    1755           8 :             pCondition = pWhereNode->getChild(1);
    1756             :         #if OSL_DEBUG_LEVEL > 0
    1757             :             sCondition = OUString();
    1758             :             pCondition->parseNodeToStr( sCondition, m_xConnection );
    1759             :         #endif
    1760           8 :             OSQLParseNode::disjunctiveNormalForm(pCondition);
    1761             : 
    1762           8 :             pCondition = pWhereNode->getChild(1);
    1763             :         #if OSL_DEBUG_LEVEL > 0
    1764             :             sCondition = OUString();
    1765             :             pCondition->parseNodeToStr( sCondition, m_xConnection );
    1766             :         #endif
    1767           8 :             OSQLParseNode::absorptions(pCondition);
    1768             : 
    1769           8 :             pCondition = pWhereNode->getChild(1);
    1770             :         #if OSL_DEBUG_LEVEL > 0
    1771             :             sCondition = OUString();
    1772             :             pCondition->parseNodeToStr( sCondition, m_xConnection );
    1773             :         #endif
    1774           8 :             if ( pCondition )
    1775             :             {
    1776           8 :                 ::std::vector< ::std::vector < PropertyValue > > aFilters;
    1777          16 :                 Reference< XNumberFormatter > xFormatter( NumberFormatter::create(m_aContext), UNO_QUERY_THROW );
    1778           8 :                 xFormatter->attachNumberFormatsSupplier( m_xNumberFormatsSupplier );
    1779             : 
    1780           8 :                 if (setORCriteria(pCondition, m_aAdditiveIterator, aFilters, xFormatter))
    1781             :                 {
    1782           8 :                     aFilterSeq.realloc(aFilters.size());
    1783           8 :                     Sequence<PropertyValue>* pFilters = aFilterSeq.getArray();
    1784           8 :                     ::std::vector< ::std::vector < PropertyValue > >::const_iterator aEnd = aFilters.end();
    1785           8 :                     ::std::vector< ::std::vector < PropertyValue > >::const_iterator i = aFilters.begin();
    1786          48 :                     for ( ; i != aEnd ; ++i)
    1787             :                     {
    1788          40 :                         const ::std::vector < PropertyValue >& rProperties = *i;
    1789          40 :                         pFilters->realloc(rProperties.size());
    1790          40 :                         PropertyValue* pFilter = pFilters->getArray();
    1791          40 :                         ::std::vector < PropertyValue >::const_iterator j = rProperties.begin();
    1792          40 :                         ::std::vector < PropertyValue >::const_iterator aEnd2 = rProperties.end();
    1793         112 :                         for ( ; j != aEnd2 ; ++j)
    1794             :                         {
    1795          72 :                             *pFilter = *j;
    1796          72 :                             ++pFilter;
    1797             :                         }
    1798          40 :                         ++pFilters;
    1799             :                     }
    1800           8 :                 }
    1801             :             }
    1802             :             // restore
    1803           8 :             m_aAdditiveIterator.setParseTree(pTempNode);
    1804           8 :         }
    1805             :     }
    1806          16 :     return aFilterSeq;
    1807             : }
    1808             : 
    1809        1665 : OUString OSingleSelectQueryComposer::getKeyword( SQLPart _ePart ) const
    1810             : {
    1811        1665 :     OUString sKeyword;
    1812        1665 :     switch(_ePart)
    1813             :     {
    1814             :         default:
    1815             :             SAL_WARN("dbaccess", "OSingleSelectQueryComposer::getKeyWord: Invalid enum value!" );
    1816             :             // no break, fallback to WHERE
    1817             :         case Where:
    1818         513 :             sKeyword = STR_WHERE;
    1819         513 :             break;
    1820             :         case Group:
    1821         394 :             sKeyword = STR_GROUP_BY;
    1822         394 :             break;
    1823             :         case Having:
    1824         377 :             sKeyword = STR_HAVING;
    1825         377 :             break;
    1826             :         case Order:
    1827         381 :             sKeyword = STR_ORDER_BY;
    1828         381 :             break;
    1829             :     }
    1830        1665 :     return sKeyword;
    1831             : }
    1832             : 
    1833        1557 : OUString OSingleSelectQueryComposer::getSQLPart( SQLPart _ePart, OSQLParseTreeIterator& _rIterator, bool _bWithKeyword )
    1834             : {
    1835        1557 :     TGetParseNode F_tmp(&OSQLParseTreeIterator::getSimpleWhereTree);
    1836        1557 :     OUString sKeyword( getKeyword( _ePart ) );
    1837        1557 :     switch(_ePart)
    1838             :     {
    1839             :         case Where:
    1840         473 :             F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleWhereTree);
    1841         473 :             break;
    1842             :         case Group:
    1843         382 :             F_tmp = TGetParseNode (&OSQLParseTreeIterator::getSimpleGroupByTree);
    1844         382 :             break;
    1845             :         case Having:
    1846         341 :             F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleHavingTree);
    1847         341 :             break;
    1848             :         case Order:
    1849         361 :             F_tmp = TGetParseNode(&OSQLParseTreeIterator::getSimpleOrderTree);
    1850         361 :             break;
    1851             :         default:
    1852             :             SAL_WARN("dbaccess","Invalid enum value!");
    1853             :     }
    1854             : 
    1855        1557 :     OUString sRet = getStatementPart( F_tmp, _rIterator );
    1856        1557 :     if ( _bWithKeyword && !sRet.isEmpty() )
    1857         148 :         sRet = sKeyword + sRet;
    1858        1557 :     return sRet;
    1859             : }
    1860             : 
    1861             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10