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

Generated by: LCOV version 1.10