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