LCOV - code coverage report
Current view: top level - dbaccess/source/core/api - SingleSelectQueryComposer.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 617 925 66.7 %
Date: 2014-04-11 Functions: 65 69 94.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10