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