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