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

Generated by: LCOV version 1.11