Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "connectivity/sqliterator.hxx"
21 : : #include "connectivity/sdbcx/VTable.hxx"
22 : : #include <connectivity/sqlparse.hxx>
23 : : #include <connectivity/dbtools.hxx>
24 : : #include <connectivity/sqlerror.hxx>
25 : : #include <com/sun/star/sdbc/ColumnValue.hpp>
26 : : #include <com/sun/star/sdbc/DataType.hpp>
27 : : #include <com/sun/star/sdbc/XRow.hpp>
28 : : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
29 : : #include <com/sun/star/sdb/ErrorCondition.hpp>
30 : : #ifdef SQL_TEST_PARSETREEITERATOR
31 : : #include <iostream>
32 : : #endif
33 : : #include "connectivity/PColumn.hxx"
34 : : #include "connectivity/dbtools.hxx"
35 : : #include <tools/diagnose_ex.h>
36 : : #include "TConnection.hxx"
37 : : #include <comphelper/types.hxx>
38 : : #include <connectivity/dbmetadata.hxx>
39 : : #include <com/sun/star/sdb/SQLFilterOperator.hpp>
40 : : #include "diagnose_ex.h"
41 : : #include <rtl/logfile.hxx>
42 : :
43 : : using namespace ::comphelper;
44 : : using namespace ::connectivity;
45 : : using namespace ::connectivity::sdbcx;
46 : : using namespace ::dbtools;
47 : : using namespace ::connectivity::parse;
48 : : using namespace ::com::sun::star;
49 : : using namespace ::com::sun::star::uno;
50 : : using namespace ::com::sun::star::container;
51 : : using namespace ::com::sun::star::sdbcx;
52 : : using namespace ::com::sun::star::beans;
53 : : using namespace ::com::sun::star::sdbc;
54 : : using namespace ::com::sun::star::sdb;
55 : :
56 : : namespace connectivity
57 : : {
58 [ + - ][ + - ]: 284 : struct OSQLParseTreeIteratorImpl
[ + - ]
59 : : {
60 : : ::std::vector< TNodePair > m_aJoinConditions;
61 : : Reference< XConnection > m_xConnection;
62 : : Reference< XDatabaseMetaData > m_xDatabaseMetaData;
63 : : Reference< XNameAccess > m_xTableContainer;
64 : : Reference< XNameAccess > m_xQueryContainer;
65 : :
66 : : ::boost::shared_ptr< OSQLTables > m_pTables; // all tables which participate in the SQL statement
67 : : ::boost::shared_ptr< OSQLTables > m_pSubTables; // all tables from sub queries not the tables from the select tables
68 : : ::boost::shared_ptr< QueryNameSet > m_pForbiddenQueryNames;
69 : :
70 : : sal_uInt32 m_nIncludeMask;
71 : :
72 : : bool m_bIsCaseSensitive;
73 : :
74 : 284 : OSQLParseTreeIteratorImpl( const Reference< XConnection >& _rxConnection, const Reference< XNameAccess >& _rxTables )
75 : : :m_xConnection( _rxConnection )
76 : : ,m_nIncludeMask( OSQLParseTreeIterator::All )
77 [ + - ][ + - ]: 284 : ,m_bIsCaseSensitive( true )
[ + - ]
78 : : {
79 : : OSL_PRECOND( m_xConnection.is(), "OSQLParseTreeIteratorImpl::OSQLParseTreeIteratorImpl: invalid connection!" );
80 [ + - ][ + - ]: 284 : m_xDatabaseMetaData = m_xConnection->getMetaData();
[ + - ]
81 : :
82 [ + - ][ + - ]: 284 : m_bIsCaseSensitive = m_xDatabaseMetaData.is() && m_xDatabaseMetaData->supportsMixedCaseQuotedIdentifiers();
[ + - ][ + - ]
83 [ + - ][ + - ]: 284 : m_pTables.reset( new OSQLTables( m_bIsCaseSensitive ) );
[ + - ]
84 [ + - ][ + - ]: 284 : m_pSubTables.reset( new OSQLTables( m_bIsCaseSensitive ) );
[ + - ]
85 : :
86 [ + - ]: 284 : m_xTableContainer = _rxTables;
87 : :
88 [ + - ]: 284 : DatabaseMetaData aMetaData( m_xConnection );
89 [ + - ][ - + ]: 284 : if ( aMetaData.supportsSubqueriesInFrom() )
90 : : {
91 : : // connections might support the XQueriesSupplier interface, if they implement the css.sdb.Connection
92 : : // service
93 [ # # ]: 0 : Reference< XQueriesSupplier > xSuppQueries( m_xConnection, UNO_QUERY );
94 [ # # ]: 0 : if ( xSuppQueries.is() )
95 [ # # ][ # # ]: 0 : m_xQueryContainer = xSuppQueries->getQueries();
[ # # ]
96 [ + - ]: 284 : }
97 : 284 : }
98 : :
99 : : public:
100 : 0 : inline bool isQueryAllowed( const ::rtl::OUString& _rQueryName )
101 : : {
102 [ # # ]: 0 : if ( !m_pForbiddenQueryNames.get() )
103 : 0 : return true;
104 [ # # ][ # # ]: 0 : if ( m_pForbiddenQueryNames->find( _rQueryName ) == m_pForbiddenQueryNames->end() )
105 : 0 : return true;
106 : 0 : return false;
107 : : }
108 : : };
109 : :
110 : : //-------------------------------------------------------------------------
111 : : /** helper class for temporarily adding a query name to a list of forbidden query names
112 : : */
113 : : class ForbidQueryName
114 : : {
115 : : ::boost::shared_ptr< QueryNameSet >& m_rpAllForbiddenNames;
116 : : ::rtl::OUString m_sForbiddenQueryName;
117 : :
118 : : public:
119 : 0 : ForbidQueryName( OSQLParseTreeIteratorImpl& _rIteratorImpl, const ::rtl::OUString _rForbiddenQueryName )
120 : : :m_rpAllForbiddenNames( _rIteratorImpl.m_pForbiddenQueryNames )
121 : 0 : ,m_sForbiddenQueryName( _rForbiddenQueryName )
122 : : {
123 [ # # ]: 0 : if ( !m_rpAllForbiddenNames.get() )
124 [ # # ][ # # ]: 0 : m_rpAllForbiddenNames.reset( new QueryNameSet );
[ # # ]
125 [ # # ]: 0 : m_rpAllForbiddenNames->insert( m_sForbiddenQueryName );
126 : 0 : }
127 : :
128 : 0 : ~ForbidQueryName()
129 : 0 : {
130 [ # # ]: 0 : m_rpAllForbiddenNames->erase( m_sForbiddenQueryName );
131 : 0 : }
132 : : };
133 : : }
134 : : //-----------------------------------------------------------------------------
135 : 284 : OSQLParseTreeIterator::OSQLParseTreeIterator(const Reference< XConnection >& _rxConnection,
136 : : const Reference< XNameAccess >& _rxTables,
137 : : const OSQLParser& _rParser,
138 : : const OSQLParseNode* pRoot )
139 : : :m_rParser( _rParser )
140 [ + - ][ + - ]: 284 : ,m_pImpl( new OSQLParseTreeIteratorImpl( _rxConnection, _rxTables ) )
141 : : {
142 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::OSQLParseTreeIterator" );
143 [ + - ]: 284 : setParseTree(pRoot);
144 : 284 : }
145 : :
146 : : //-----------------------------------------------------------------------------
147 : 0 : OSQLParseTreeIterator::OSQLParseTreeIterator( const OSQLParseTreeIterator& _rParentIterator, const OSQLParser& _rParser, const OSQLParseNode* pRoot )
148 : : :m_rParser( _rParser )
149 [ # # ][ # # ]: 0 : ,m_pImpl( new OSQLParseTreeIteratorImpl( _rParentIterator.m_pImpl->m_xConnection, _rParentIterator.m_pImpl->m_xTableContainer ) )
150 : : {
151 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::OSQLParseTreeIterator" );
152 [ # # ]: 0 : m_pImpl->m_pForbiddenQueryNames = _rParentIterator.m_pImpl->m_pForbiddenQueryNames;
153 [ # # ]: 0 : setParseTree( pRoot );
154 : 0 : }
155 : :
156 : : //-----------------------------------------------------------------------------
157 [ + - ][ + - ]: 284 : OSQLParseTreeIterator::~OSQLParseTreeIterator()
[ + - ][ + - ]
[ + - ][ + - ]
158 : : {
159 [ + - ]: 284 : dispose();
160 : 284 : }
161 : :
162 : : // -----------------------------------------------------------------------------
163 : 342 : const OSQLTables& OSQLParseTreeIterator::getTables() const
164 : : {
165 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getTables" );
166 : 342 : return *m_pImpl->m_pTables;
167 : : }
168 : :
169 : : // -----------------------------------------------------------------------------
170 : 7058 : bool OSQLParseTreeIterator::isCaseSensitive() const
171 : : {
172 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::isCaseSensitive" );
173 : 7058 : return m_pImpl->m_bIsCaseSensitive;
174 : : }
175 : :
176 : : // -----------------------------------------------------------------------------
177 : 568 : void OSQLParseTreeIterator::dispose()
178 : : {
179 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::dispose" );
180 : 568 : m_aSelectColumns = NULL;
181 : 568 : m_aGroupColumns = NULL;
182 : 568 : m_aOrderColumns = NULL;
183 : 568 : m_aParameters = NULL;
184 : 568 : m_pImpl->m_xTableContainer = NULL;
185 : 568 : m_pImpl->m_xDatabaseMetaData = NULL;
186 : 568 : m_aCreateColumns = NULL;
187 : 568 : m_pImpl->m_pTables->clear();
188 : 568 : m_pImpl->m_pSubTables->clear();
189 : 568 : }
190 : : //-----------------------------------------------------------------------------
191 : 860 : void OSQLParseTreeIterator::setParseTree(const OSQLParseNode * pNewParseTree)
192 : : {
193 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setParseTree" );
194 : 860 : m_pImpl->m_pTables->clear();
195 : 860 : m_pImpl->m_pSubTables->clear();
196 : :
197 [ + - ]: 860 : m_aSelectColumns = new OSQLColumns();
198 [ + - ]: 860 : m_aGroupColumns = new OSQLColumns();
199 [ + - ]: 860 : m_aOrderColumns = new OSQLColumns();
200 [ + - ]: 860 : m_aParameters = new OSQLColumns();
201 [ + - ]: 860 : m_aCreateColumns = new OSQLColumns();
202 : :
203 : 860 : m_pParseTree = pNewParseTree;
204 [ + + ]: 860 : if (!m_pParseTree)
205 : : {
206 : 436 : m_eStatementType = SQL_STATEMENT_UNKNOWN;
207 : 436 : return;
208 : : }
209 : :
210 : : // If m_pParseTree, but no connection then return
211 [ - + ]: 424 : if ( !m_pImpl->m_xTableContainer.is() )
212 : 0 : return;
213 : :
214 [ + - ]: 424 : m_aErrors = SQLException();
215 : :
216 : :
217 : : // Determine statement type ...
218 [ - + ][ # # ]: 424 : if (SQL_ISRULE(m_pParseTree,select_statement) || SQL_ISRULE(m_pParseTree,union_statement) )
[ # # ][ + - ]
[ + - ]
219 : : {
220 : 424 : m_eStatementType = SQL_STATEMENT_SELECT;
221 : : }
222 [ # # ][ # # ]: 0 : else if (SQL_ISRULE(m_pParseTree,insert_statement))
[ # # ]
223 : : {
224 : 0 : m_eStatementType = SQL_STATEMENT_INSERT;
225 : : }
226 [ # # ][ # # ]: 0 : else if (SQL_ISRULE(m_pParseTree,update_statement_searched))
[ # # ]
227 : : {
228 : 0 : m_eStatementType = SQL_STATEMENT_UPDATE;
229 : : }
230 [ # # ][ # # ]: 0 : else if (SQL_ISRULE(m_pParseTree,delete_statement_searched))
[ # # ]
231 : : {
232 : 0 : m_eStatementType = SQL_STATEMENT_DELETE;
233 : : }
234 [ # # ][ # # ]: 0 : else if (m_pParseTree->count() == 3 && SQL_ISRULE(m_pParseTree->getChild(1),odbc_call_spec))
[ # # ][ # # ]
235 : : {
236 : 0 : m_eStatementType = SQL_STATEMENT_ODBC_CALL;
237 : : }
238 [ # # ][ # # ]: 0 : else if (SQL_ISRULE(m_pParseTree->getChild(0),base_table_def))
[ # # ]
239 : : {
240 : 0 : m_eStatementType = SQL_STATEMENT_CREATE_TABLE;
241 : 0 : m_pParseTree = m_pParseTree->getChild(0);
242 : : }
243 : : else
244 : : {
245 : 0 : m_eStatementType = SQL_STATEMENT_UNKNOWN;
246 : : //aIteratorStatus.setInvalidStatement();
247 : 860 : return;
248 : : }
249 : : }
250 : :
251 : : //-----------------------------------------------------------------------------
252 : : namespace
253 : : {
254 : : //.........................................................................
255 : 0 : static void impl_getRowString( const Reference< XRow >& _rxRow, const sal_Int32 _nColumnIndex, ::rtl::OUString& _out_rString )
256 : : {
257 : 0 : _out_rString = _rxRow->getString( _nColumnIndex );
258 [ # # ]: 0 : if ( _rxRow->wasNull() )
259 : 0 : _out_rString= ::rtl::OUString();
260 : 0 : }
261 : :
262 : : //.........................................................................
263 : 88 : static ::rtl::OUString lcl_findTableInMetaData(
264 : : const Reference< XDatabaseMetaData >& _rxDBMeta, const ::rtl::OUString& _rCatalog,
265 : : const ::rtl::OUString& _rSchema, const ::rtl::OUString& _rTableName )
266 : : {
267 : 88 : ::rtl::OUString sComposedName;
268 : :
269 [ + - ][ + + ]: 88 : static const ::rtl::OUString s_sTableTypeView("VIEW");
270 [ + + ][ + - ]: 88 : static const ::rtl::OUString s_sTableTypeTable("TABLE");
271 [ + + ][ + - ]: 88 : static const ::rtl::OUString s_sWildcard( "%" );
272 : :
273 : : // we want all catalogues, all schemas, all tables
274 [ + - ]: 88 : Sequence< ::rtl::OUString > sTableTypes(3);
275 [ + - ]: 88 : sTableTypes[0] = s_sTableTypeView;
276 [ + - ]: 88 : sTableTypes[1] = s_sTableTypeTable;
277 [ + - ]: 88 : sTableTypes[2] = s_sWildcard; // just to be sure to include anything else ....
278 : :
279 [ + - ]: 88 : if ( _rxDBMeta.is() )
280 : : {
281 : 88 : sComposedName = ::rtl::OUString();
282 : :
283 [ + - ]: 88 : Reference< XResultSet> xRes = _rxDBMeta->getTables(
284 [ - + ][ - + ]: 88 : !_rCatalog.isEmpty() ? makeAny( _rCatalog ) : Any(), !_rSchema.isEmpty() ? _rSchema : s_sWildcard, _rTableName, sTableTypes );
[ # # ][ + - ]
285 : :
286 [ + - ]: 88 : Reference< XRow > xCurrentRow( xRes, UNO_QUERY );
287 [ + - ][ + - ]: 88 : if ( xCurrentRow.is() && xRes->next() )
[ + - ][ - + ]
[ - + ]
288 : : {
289 : 0 : ::rtl::OUString sCatalog, sSchema, sName;
290 : :
291 [ # # ]: 0 : impl_getRowString( xCurrentRow, 1, sCatalog );
292 [ # # ]: 0 : impl_getRowString( xCurrentRow, 2, sSchema );
293 [ # # ]: 0 : impl_getRowString( xCurrentRow, 3, sName );
294 : :
295 : : sComposedName = ::dbtools::composeTableName(
296 : : _rxDBMeta,
297 : : sCatalog,
298 : : sSchema,
299 : : sName,
300 : : sal_False,
301 : : ::dbtools::eInDataManipulation
302 [ # # ]: 0 : );
303 : 88 : }
304 : : }
305 [ + - ]: 88 : return sComposedName;
306 : : }
307 : : }
308 : :
309 : : //-----------------------------------------------------------------------------
310 : 0 : void OSQLParseTreeIterator::impl_getQueryParameterColumns( const OSQLTable& _rQuery )
311 : : {
312 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_getQueryParameterColumns" );
313 [ # # ]: 0 : if ( ( m_pImpl->m_nIncludeMask & Parameters ) != Parameters )
314 : : // parameters not to be included in the traversal
315 : 0 : return;
316 : :
317 [ # # ][ # # ]: 0 : ::rtl::Reference< OSQLColumns > pSubQueryParameterColumns( new OSQLColumns() );
318 : :
319 : : // get the command and the EscapeProcessing properties from the sub query
320 : 0 : ::rtl::OUString sSubQueryCommand;
321 : 0 : sal_Bool bEscapeProcessing = sal_False;
322 : : try
323 : : {
324 [ # # ]: 0 : Reference< XPropertySet > xQueryProperties( _rQuery, UNO_QUERY_THROW );
325 [ # # ][ # # ]: 0 : OSL_VERIFY( xQueryProperties->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_COMMAND ) ) >>= sSubQueryCommand );
[ # # ][ # # ]
326 [ # # ][ # # ]: 0 : OSL_VERIFY( xQueryProperties->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING ) ) >>= bEscapeProcessing );
[ # # ][ # # ]
[ # # ]
327 : : }
328 [ # # ]: 0 : catch( const Exception& )
329 : : {
330 : : DBG_UNHANDLED_EXCEPTION();
331 : : }
332 : :
333 : : // parse the sub query
334 : : do {
335 : :
336 [ # # ][ # # ]: 0 : if ( !bEscapeProcessing || ( sSubQueryCommand.isEmpty() ) )
[ # # ]
337 : : break;
338 : :
339 : 0 : ::rtl::OUString sError;
340 [ # # ]: 0 : ::std::auto_ptr< OSQLParseNode > pSubQueryNode( const_cast< OSQLParser& >( m_rParser ).parseTree( sError, sSubQueryCommand, sal_False ) );
341 [ # # ]: 0 : if ( !pSubQueryNode.get() )
342 : : break;
343 : :
344 [ # # ]: 0 : OSQLParseTreeIterator aSubQueryIterator( *this, m_rParser, pSubQueryNode.get() );
345 [ # # ]: 0 : aSubQueryIterator.traverseSome( Parameters | SelectColumns );
346 : : // SelectColumns might also contain parameters
347 : : // #i77635# - 2007-07-23 / frank.schoenheit@sun.com
348 [ # # ][ # # ]: 0 : pSubQueryParameterColumns = aSubQueryIterator.getParameters();
[ # # ]
349 [ # # ][ # # ]: 0 : aSubQueryIterator.dispose();
[ # # ][ # # ]
[ # # ]
350 : :
351 : : } while ( false );
352 : :
353 : : // copy the parameters of the sub query to our own parameter array
354 : 0 : ::std::copy( pSubQueryParameterColumns->get().begin(), pSubQueryParameterColumns->get().end(),
355 [ # # ][ # # ]: 0 : ::std::insert_iterator< OSQLColumns::Vector >( m_aParameters->get(), m_aParameters->get().end() ) );
356 : : }
357 : :
358 : : //-----------------------------------------------------------------------------
359 : 408 : OSQLTable OSQLParseTreeIterator::impl_locateRecordSource( const ::rtl::OUString& _rComposedName )
360 : : {
361 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_locateRecordSource" );
362 [ - + ]: 408 : if ( _rComposedName.isEmpty() )
363 : : {
364 : : OSL_FAIL( "OSQLParseTreeIterator::impl_locateRecordSource: no object name at all?" );
365 : 0 : return OSQLTable();
366 : : }
367 : :
368 : 408 : OSQLTable aReturn;
369 : 408 : ::rtl::OUString sComposedName( _rComposedName );
370 : :
371 : : try
372 : : {
373 : 408 : ::rtl::OUString sCatalog, sSchema, sName;
374 [ + - ]: 408 : qualifiedNameComponents( m_pImpl->m_xDatabaseMetaData, sComposedName, sCatalog, sSchema, sName, ::dbtools::eInDataManipulation );
375 : :
376 : : // check whether there is a query with the given name
377 [ - + ][ # # ]: 408 : bool bQueryDoesExist = m_pImpl->m_xQueryContainer.is() && m_pImpl->m_xQueryContainer->hasByName( sComposedName );
[ # # ][ # # ]
378 : :
379 : : // check whether the table container contains an object with the given name
380 [ + - ][ + - ]: 408 : if ( !bQueryDoesExist && !m_pImpl->m_xTableContainer->hasByName( sComposedName ) )
[ + - ][ + + ]
[ + + ]
381 [ + - ]: 88 : sComposedName = lcl_findTableInMetaData( m_pImpl->m_xDatabaseMetaData, sCatalog, sSchema, sName );
382 [ + - ][ + - ]: 408 : bool bTableDoesExist = m_pImpl->m_xTableContainer->hasByName( sComposedName );
383 : :
384 : : // now obtain the object
385 : :
386 : : // if we're creating a table, and there already is a table or query with the same name,
387 : : // this is worth an error
388 [ - + ]: 408 : if ( SQL_STATEMENT_CREATE_TABLE == m_eStatementType )
389 : : {
390 [ # # ]: 0 : if ( bQueryDoesExist )
391 [ # # ]: 0 : impl_appendError( IParseContext::ERROR_INVALID_QUERY_EXIST, &sName );
392 [ # # ]: 0 : else if ( bTableDoesExist )
393 [ # # ]: 0 : impl_appendError( IParseContext::ERROR_INVALID_TABLE_EXIST, &sName );
394 : : else
395 [ # # ][ # # ]: 0 : aReturn = impl_createTableObject( sName, sCatalog, sSchema );
396 : : }
397 : : else
398 : : {
399 : : // queries win over tables, so if there's a query with this name, take this, no matter if
400 : : // there's a table, too
401 [ - + ]: 408 : if ( bQueryDoesExist )
402 : : {
403 [ # # ][ # # ]: 0 : if ( !m_pImpl->isQueryAllowed( sComposedName ) )
404 : : {
405 [ # # ][ # # ]: 0 : impl_appendError( m_rParser.getErrorHelper().getSQLException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES, NULL ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
406 [ # # ]: 0 : return NULL;
407 : : }
408 : :
409 [ # # ][ # # ]: 0 : m_pImpl->m_xQueryContainer->getByName( sComposedName ) >>= aReturn;
[ # # ]
410 : :
411 : : // collect the parameters from the sub query
412 [ # # ]: 0 : ForbidQueryName aForbidName( *m_pImpl, sComposedName );
413 [ # # ][ # # ]: 0 : impl_getQueryParameterColumns( aReturn );
414 : : }
415 [ + + ]: 408 : else if ( bTableDoesExist )
416 [ + - ][ + - ]: 320 : m_pImpl->m_xTableContainer->getByName( sComposedName ) >>= aReturn;
[ + - ]
417 : : else
418 : : {
419 [ - + ]: 88 : if ( m_pImpl->m_xQueryContainer.is() )
420 : : // the connection on which we're working supports sub queries in from (else
421 : : // m_xQueryContainer would not have been set), so emit a better error message
422 [ # # ]: 0 : impl_appendError( IParseContext::ERROR_INVALID_TABLE_OR_QUERY, &sName );
423 : : else
424 [ + - ]: 408 : impl_appendError( IParseContext::ERROR_INVALID_TABLE, &sName );
425 : : }
426 [ - + ][ - + ]: 408 : }
[ + - ]
427 : : }
428 [ # # # # ]: 0 : catch(Exception&)
429 : : {
430 [ # # ]: 0 : impl_appendError( IParseContext::ERROR_INVALID_TABLE, &sComposedName );
431 : : }
432 : :
433 : 408 : return aReturn;
434 : : }
435 : :
436 : : //-----------------------------------------------------------------------------
437 : 408 : void OSQLParseTreeIterator::traverseOneTableName( OSQLTables& _rTables,const OSQLParseNode * pTableName, const ::rtl::OUString & rTableRange )
438 : : {
439 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseOneTableName" );
440 [ + - ]: 408 : if ( ( m_pImpl->m_nIncludeMask & TableNames ) != TableNames )
441 : : // tables should not be included in the traversal
442 : 408 : return;
443 : :
444 : : OSL_ENSURE(pTableName != NULL,"OSQLParseTreeIterator::traverseOneTableName: pTableName == NULL");
445 : :
446 : 408 : Any aCatalog;
447 : 408 : ::rtl::OUString aSchema,aTableName,aComposedName;
448 : 408 : ::rtl::OUString aTableRange(rTableRange);
449 : :
450 : : // Get table name
451 [ + - ]: 408 : OSQLParseNode::getTableComponents(pTableName,aCatalog,aSchema,aTableName,m_pImpl->m_xDatabaseMetaData);
452 : :
453 : : // create the composed name like DOMAIN.USER.TABLE1
454 : 408 : aComposedName = ::dbtools::composeTableName(m_pImpl->m_xDatabaseMetaData,
455 : 408 : aCatalog.hasValue() ? ::comphelper::getString(aCatalog) : ::rtl::OUString(),
456 : : aSchema,
457 : : aTableName,
458 : : sal_False,
459 [ # # ][ + - ]: 816 : ::dbtools::eInDataManipulation);
[ - + ]
460 : :
461 : : // if there is no alias for the table name assign the orignal name to it
462 [ + + ]: 408 : if ( aTableRange.isEmpty() )
463 : 304 : aTableRange = aComposedName;
464 : :
465 : : // get the object representing this table/query
466 [ + - ]: 408 : OSQLTable aTable = impl_locateRecordSource( aComposedName );
467 [ + + ]: 408 : if ( aTable.is() )
468 [ + - ][ + - ]: 408 : _rTables[ aTableRange ] = aTable;
469 : : }
470 : : //-----------------------------------------------------------------------------
471 : 850 : void OSQLParseTreeIterator::impl_fillJoinConditions(const OSQLParseNode* i_pJoinCondition)
472 : : {
473 [ + - - + : 1700 : if (i_pJoinCondition->count() == 3 && // Expression with brackets
# # # # #
# ][ - + ]
474 : 850 : SQL_ISPUNCTUATION(i_pJoinCondition->getChild(0),"(") &&
475 : 0 : SQL_ISPUNCTUATION(i_pJoinCondition->getChild(2),")"))
476 : : {
477 : 0 : impl_fillJoinConditions(i_pJoinCondition->getChild(1));
478 : : }
479 [ + - ][ + - ]: 850 : else if (SQL_ISRULEOR2(i_pJoinCondition,search_condition,boolean_term) && // AND/OR logic operation:
[ - + # # ]
[ - + ]
480 : 0 : i_pJoinCondition->count() == 3)
481 : : {
482 : : // Only allow AND logic operation
483 [ # # ][ # # ]: 0 : if ( SQL_ISTOKEN(i_pJoinCondition->getChild(1),AND) )
[ # # ]
484 : : {
485 : 0 : impl_fillJoinConditions(i_pJoinCondition->getChild(0));
486 : 0 : impl_fillJoinConditions(i_pJoinCondition->getChild(1));
487 : : }
488 : : }
489 [ + - ][ + - ]: 850 : else if (SQL_ISRULE(i_pJoinCondition,comparison_predicate))
[ + - ]
490 : : {
491 : : // only the comparison of columns is allowed
492 : : OSL_ENSURE(i_pJoinCondition->count() == 3,"OQueryDesignView::InsertJoinConnection: error in the parse tree");
493 [ + + ][ + - : 1690 : if (SQL_ISRULE(i_pJoinCondition->getChild(0),column_ref) &&
+ + - + #
# ][ - + ]
494 : 840 : SQL_ISRULE(i_pJoinCondition->getChild(2),column_ref) &&
495 : 0 : i_pJoinCondition->getChild(1)->getNodeType() == SQL_NODE_EQUAL)
496 : : {
497 [ # # ][ # # ]: 0 : m_pImpl->m_aJoinConditions.push_back( TNodePair(i_pJoinCondition->getChild(0),i_pJoinCondition->getChild(2)) );
[ # # ]
498 : : }
499 : : }
500 : 850 : }
501 : : //-----------------------------------------------------------------------------
502 : 0 : ::std::vector< TNodePair >& OSQLParseTreeIterator::getJoinConditions() const
503 : : {
504 : 0 : return m_pImpl->m_aJoinConditions;
505 : : }
506 : : //-----------------------------------------------------------------------------
507 : 0 : void OSQLParseTreeIterator::getQualified_join( OSQLTables& _rTables, const OSQLParseNode *pTableRef, ::rtl::OUString& aTableRange )
508 : : {
509 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getQualified_join" );
510 : : OSL_PRECOND( SQL_ISRULE( pTableRef, cross_union ) || SQL_ISRULE( pTableRef, qualified_join ) ,
511 : : "OSQLParseTreeIterator::getQualified_join: illegal node!" );
512 : :
513 : 0 : aTableRange = ::rtl::OUString();
514 : :
515 : 0 : const OSQLParseNode* pNode = getTableNode(_rTables,pTableRef->getChild(0),aTableRange);
516 [ # # ]: 0 : if ( isTableNode( pNode ) )
517 : 0 : traverseOneTableName( _rTables, pNode, aTableRange );
518 : :
519 : 0 : sal_uInt32 nPos = 4;
520 [ # # ][ # # ]: 0 : if( SQL_ISRULE(pTableRef,cross_union) || pTableRef->getChild(1)->getTokenID() != SQL_TOKEN_NATURAL)
[ # # ][ # # ]
521 : : {
522 : 0 : nPos = 3;
523 : : // join_condition,named_columns_join
524 [ # # ][ # # ]: 0 : if ( SQL_ISRULE( pTableRef, qualified_join ) )
[ # # ]
525 : : {
526 : 0 : const OSQLParseNode* pJoin_spec = pTableRef->getChild(4);
527 [ # # ][ # # ]: 0 : if ( SQL_ISRULE( pJoin_spec, join_condition ) )
[ # # ]
528 : : {
529 : 0 : impl_fillJoinConditions(pJoin_spec->getChild(1));
530 : : }
531 : : else
532 : : {
533 : 0 : const OSQLParseNode* pColumnCommalist = pJoin_spec->getChild(2);
534 : : // All columns in the column_commalist ...
535 [ # # ]: 0 : for (sal_uInt32 i = 0; i < pColumnCommalist->count(); i++)
536 : : {
537 [ # # ]: 0 : const OSQLParseNode * pCol = pColumnCommalist->getChild(i);
538 : : // add twice because the column must exists in both tables
539 [ # # ][ # # ]: 0 : m_pImpl->m_aJoinConditions.push_back( TNodePair(pCol,pCol) );
540 : : }
541 : : }
542 : : }
543 : : }
544 : :
545 : 0 : pNode = getTableNode(_rTables,pTableRef->getChild(nPos),aTableRange);
546 [ # # ]: 0 : if ( isTableNode( pNode ) )
547 : 0 : traverseOneTableName( _rTables, pNode, aTableRange );
548 : 0 : }
549 : : //-----------------------------------------------------------------------------
550 : 0 : const OSQLParseNode* OSQLParseTreeIterator::getTableNode( OSQLTables& _rTables, const OSQLParseNode *pTableRef,::rtl::OUString& rTableRange )
551 : : {
552 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getTableNode" );
553 : : OSL_PRECOND( SQL_ISRULE( pTableRef, table_ref ) || SQL_ISRULE( pTableRef, joined_table )
554 : : || SQL_ISRULE( pTableRef, qualified_join ) || SQL_ISRULE( pTableRef, cross_union ),
555 : : "OSQLParseTreeIterator::getTableNode: only to be called for table_ref nodes!" );
556 : :
557 : 0 : const OSQLParseNode* pTableNameNode = NULL;
558 : :
559 [ # # ][ # # ]: 0 : if ( SQL_ISRULE( pTableRef, joined_table ) )
[ # # ]
560 : : {
561 : 0 : getQualified_join( _rTables, pTableRef->getChild(1), rTableRange );
562 : : }
563 [ # # ][ # # ]: 0 : if ( SQL_ISRULE( pTableRef, qualified_join ) || SQL_ISRULE( pTableRef, cross_union ) )
[ # # ][ # # ]
[ # # ]
564 : : {
565 : 0 : getQualified_join( _rTables, pTableRef, rTableRange );
566 : : }
567 : : else
568 : : {
569 : 0 : rTableRange = OSQLParseNode::getTableRange(pTableRef);
570 [ # # ]: 0 : if ( ( pTableRef->count() == 4 ) // '{' SQL_TOKEN_OJ joined_table '}'
[ # # # # ]
571 : 0 : || ( pTableRef->count() == 5 ) // '(' joined_table ')' range_variable op_column_commalist
572 : : )
573 : : {
574 : 0 : getQualified_join( _rTables, pTableRef->getChild(6 - pTableRef->count()), rTableRange );
575 : : }
576 [ # # ]: 0 : else if ( pTableRef->count() == 3 ) // subquery range_variable op_column_commalist || '(' joined_table ')'
577 : : {
578 : 0 : const OSQLParseNode* pSubQuery = pTableRef->getChild(0);
579 [ # # ]: 0 : if ( pSubQuery->isToken() )
580 : : {
581 : 0 : getQualified_join( _rTables, pTableRef->getChild(1), rTableRange );
582 : : }
583 : : else
584 : : {
585 : : OSL_ENSURE( pSubQuery->count() == 3, "sub queries should have 3 children!" );
586 : 0 : const OSQLParseNode* pQueryExpression = pSubQuery->getChild(1);
587 [ # # ][ # # ]: 0 : if ( SQL_ISRULE( pQueryExpression, select_statement ) )
[ # # ]
588 : : {
589 : 0 : getSelect_statement( *m_pImpl->m_pSubTables, pQueryExpression );
590 : : }
591 : : else
592 : : {
593 : : OSL_FAIL( "OSQLParseTreeIterator::getTableNode: subquery which is no select_statement: not yet implemented!" );
594 : : }
595 : : }
596 : : }
597 [ # # ]: 0 : else if ( pTableRef->count() == 2 ) // table_node table_primary_as_range_column
598 : : {
599 : 0 : pTableNameNode = pTableRef->getChild(0);
600 : : }
601 : : else
602 : : OSL_FAIL( "OSQLParseTreeIterator::getTableNode: unhandled case!" );
603 : : }
604 : :
605 : 0 : return pTableNameNode;
606 : : }
607 : : //-----------------------------------------------------------------------------
608 : 408 : void OSQLParseTreeIterator::getSelect_statement(OSQLTables& _rTables,const OSQLParseNode* pSelect)
609 : : {
610 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSelect_statement" );
611 [ + - ][ + - ]: 408 : if(SQL_ISRULE(pSelect,union_statement))
[ - + ][ - + ]
612 : : {
613 [ # # ][ # # ]: 0 : getSelect_statement(_rTables,pSelect->getChild(0));
614 : : //getSelect_statement(pSelect->getChild(3));
615 : 408 : return;
616 : : }
617 [ + - ][ + - ]: 408 : OSQLParseNode * pTableRefCommalist = pSelect->getChild(3)->getChild(0)->getChild(1);
[ + - ]
618 : :
619 : : OSL_ENSURE(pTableRefCommalist != NULL,"OSQLParseTreeIterator: error in parse tree!");
620 : : OSL_ENSURE(SQL_ISRULE(pTableRefCommalist,table_ref_commalist),"OSQLParseTreeIterator: error in parse tree!");
621 : :
622 : 408 : const OSQLParseNode* pTableName = NULL;
623 : 408 : ::rtl::OUString aTableRange;
624 [ + + ]: 816 : for (sal_uInt32 i = 0; i < pTableRefCommalist->count(); i++)
625 : : { // Process FROM clause
626 : 408 : aTableRange = ::rtl::OUString();
627 : :
628 [ + - ]: 408 : const OSQLParseNode* pTableListElement = pTableRefCommalist->getChild(i);
629 [ + - ][ - + ]: 408 : if ( isTableNode( pTableListElement ) )
630 : : {
631 [ # # ]: 0 : traverseOneTableName( _rTables, pTableListElement, aTableRange );
632 : : }
633 [ + - ][ + - ]: 408 : else if ( SQL_ISRULE( pTableListElement, table_ref ) )
[ + - ][ + - ]
634 : : {
635 : : // Table refereneces can be made up of table names, table names (+),'('joined_table')'(+)
636 [ + - ]: 408 : pTableName = pTableListElement->getChild(0);
637 [ + - ][ + - ]: 408 : if( isTableNode( pTableName ) )
638 : : { // Found table names
639 [ + - ]: 408 : aTableRange = OSQLParseNode::getTableRange(pTableListElement);
640 [ + - ]: 408 : traverseOneTableName( _rTables, pTableName, aTableRange );
641 : : }
642 [ # # ][ # # ]: 0 : else if(SQL_ISPUNCTUATION(pTableName,"{"))
[ # # ]
643 : : { // '{' SQL_TOKEN_OJ joined_table '}'
644 [ # # ][ # # ]: 0 : getQualified_join( _rTables, pTableListElement->getChild(2), aTableRange );
645 : : }
646 : : else
647 : : { // '(' joined_table ')' range_variable op_column_commalist
648 [ # # ]: 0 : getTableNode( _rTables, pTableListElement, aTableRange );
649 : : }
650 : : }
651 [ # # ][ # # ]: 0 : else if (SQL_ISRULE( pTableListElement, qualified_join ) || SQL_ISRULE( pTableListElement, cross_union ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
652 : : {
653 [ # # ]: 0 : getQualified_join( _rTables, pTableListElement, aTableRange );
654 : : }
655 [ # # ][ # # ]: 0 : else if ( SQL_ISRULE( pTableListElement, joined_table ) )
[ # # ][ # # ]
656 : : {
657 [ # # ][ # # ]: 0 : getQualified_join( _rTables, pTableListElement->getChild(1), aTableRange );
658 : : }
659 : :
660 : : // if (! aIteratorStatus.IsSuccessful()) break;
661 : 408 : }
662 : : }
663 : : //-----------------------------------------------------------------------------
664 : 408 : bool OSQLParseTreeIterator::traverseTableNames(OSQLTables& _rTables)
665 : : {
666 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseTableNames" );
667 [ - + ]: 408 : if ( m_pParseTree == NULL )
668 : 0 : return false;
669 : :
670 : 408 : OSQLParseNode* pTableName = NULL;
671 : :
672 [ + - - - ]: 408 : switch ( m_eStatementType )
673 : : {
674 : : case SQL_STATEMENT_SELECT:
675 : 408 : getSelect_statement( _rTables, m_pParseTree );
676 : 408 : break;
677 : :
678 : : case SQL_STATEMENT_CREATE_TABLE:
679 : : case SQL_STATEMENT_INSERT:
680 : : case SQL_STATEMENT_DELETE:
681 : 0 : pTableName = m_pParseTree->getChild(2);
682 : 0 : break;
683 : :
684 : : case SQL_STATEMENT_UPDATE:
685 : 0 : pTableName = m_pParseTree->getChild(1);
686 : 0 : break;
687 : : default:
688 : 0 : break;
689 : : }
690 : :
691 [ - + ]: 408 : if ( pTableName )
692 : : {
693 : 0 : ::rtl::OUString sTableRange;
694 [ # # ]: 0 : traverseOneTableName( _rTables, pTableName, sTableRange );
695 : : }
696 : :
697 : 408 : return !hasErrors();
698 : : }
699 : : //-----------------------------------------------------------------------------
700 : 388 : ::rtl::OUString OSQLParseTreeIterator::getColumnAlias(const OSQLParseNode* _pDerivedColumn)
701 : : {
702 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnAlias" );
703 : : OSL_ENSURE(SQL_ISRULE(_pDerivedColumn,derived_column),"No derived column!");
704 : 388 : ::rtl::OUString sColumnAlias;
705 [ - + ][ + - ]: 388 : if(_pDerivedColumn->getChild(1)->count() == 2)
706 [ # # ][ # # ]: 0 : sColumnAlias = _pDerivedColumn->getChild(1)->getChild(1)->getTokenValue();
707 [ + - ][ - + ]: 388 : else if(!_pDerivedColumn->getChild(1)->isRule())
708 [ # # ]: 0 : sColumnAlias = _pDerivedColumn->getChild(1)->getTokenValue();
709 : 388 : return sColumnAlias;
710 : : }
711 : :
712 : : // -----------------------------------------------------------------------------
713 : : namespace
714 : : {
715 : 3592 : void lcl_getColumnRange( const OSQLParseNode* _pColumnRef, const Reference< XConnection >& _rxConnection,
716 : : ::rtl::OUString& _out_rColumnName, ::rtl::OUString& _out_rTableRange,
717 : : const OSQLColumns* _pSelectColumns, ::rtl::OUString& _out_rColumnAliasIfPresent )
718 : : {
719 : 3592 : _out_rColumnName = _out_rTableRange = _out_rColumnAliasIfPresent = ::rtl::OUString();
720 [ + - ][ + + ]: 3592 : if ( SQL_ISRULE( _pColumnRef, column_ref ) )
[ + + ]
721 : : {
722 [ + + ]: 3544 : if( _pColumnRef->count() > 1 )
723 : : {
724 [ + + ]: 44 : for ( sal_Int32 i=0; i<((sal_Int32)_pColumnRef->count())-2; ++i )
725 : 22 : _pColumnRef->getChild(i)->parseNodeToStr( _out_rTableRange, _rxConnection, NULL, sal_False, sal_False );
726 : 22 : _out_rColumnName = _pColumnRef->getChild( _pColumnRef->count()-1 )->getChild(0)->getTokenValue();
727 : : }
728 : : else
729 : 3522 : _out_rColumnName = _pColumnRef->getChild(0)->getTokenValue();
730 : :
731 : : // look up the column in the select column, to find an possible alias
732 [ + + ]: 3544 : if ( _pSelectColumns )
733 : : {
734 [ + - ][ + + ]: 11104 : for ( OSQLColumns::Vector::const_iterator lookupColumn = _pSelectColumns->get().begin();
735 : 5552 : lookupColumn != _pSelectColumns->get().end();
736 : : ++lookupColumn
737 : : )
738 : : {
739 : 2554 : Reference< XPropertySet > xColumn( *lookupColumn );
740 : : try
741 : : {
742 : 2554 : ::rtl::OUString sName, sTableName;
743 [ + - ][ + - ]: 2554 : xColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_REALNAME ) ) >>= sName;
[ + - ][ + - ]
744 [ + - ][ + - ]: 2554 : xColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_TABLENAME ) ) >>= sTableName;
[ + - ][ + - ]
745 [ - + ][ - + ]: 2554 : if ( sName == _out_rColumnName && sTableName == _out_rTableRange )
[ + + ]
746 [ # # ][ # # ]: 2554 : xColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_NAME ) ) >>= _out_rColumnAliasIfPresent;
[ # # ][ # # ]
[ # # ]
747 : : }
748 [ # # ]: 0 : catch( const Exception& )
749 : : {
750 : : DBG_UNHANDLED_EXCEPTION();
751 : : }
752 : 2554 : }
753 : : }
754 : : }
755 [ - + ][ # # ]: 48 : else if(SQL_ISRULE(_pColumnRef,general_set_fct) || SQL_ISRULE(_pColumnRef,set_fct_spec))
[ - + ][ # # ]
[ - + ]
756 : : { // Function
757 : 0 : _pColumnRef->parseNodeToStr( _out_rColumnName, _rxConnection );
758 : : }
759 [ - + ]: 48 : else if(_pColumnRef->getNodeType() == SQL_NODE_NAME)
760 : 0 : _out_rColumnName = _pColumnRef->getTokenValue();
761 : 3592 : }
762 : : }
763 : :
764 : : // -----------------------------------------------------------------------------
765 : 546 : void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode* _pColumnRef,
766 : : ::rtl::OUString& _rColumnName,
767 : : ::rtl::OUString& _rTableRange) const
768 : : {
769 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnRange" );
770 : 546 : ::rtl::OUString sDummy;
771 [ + - ]: 546 : lcl_getColumnRange( _pColumnRef, m_pImpl->m_xConnection, _rColumnName, _rTableRange, NULL, sDummy );
772 : 546 : }
773 : :
774 : : // -----------------------------------------------------------------------------
775 : 3046 : void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode* _pColumnRef,
776 : : ::rtl::OUString& _rColumnName,
777 : : ::rtl::OUString& _rTableRange,
778 : : ::rtl::OUString& _out_rColumnAliasIfPresent ) const
779 : : {
780 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnRange" );
781 : 3046 : lcl_getColumnRange( _pColumnRef, m_pImpl->m_xConnection, _rColumnName, _rTableRange, &*m_aSelectColumns, _out_rColumnAliasIfPresent );
782 : 3046 : }
783 : :
784 : : //-----------------------------------------------------------------------------
785 : 0 : void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode* _pColumnRef,
786 : : const Reference< XConnection >& _rxConnection, ::rtl::OUString& _out_rColumnName, ::rtl::OUString& _out_rTableRange )
787 : : {
788 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnRange" );
789 : 0 : ::rtl::OUString sDummy;
790 [ # # ]: 0 : lcl_getColumnRange( _pColumnRef, _rxConnection, _out_rColumnName, _out_rTableRange, NULL, sDummy );
791 : 0 : }
792 : :
793 : : //-----------------------------------------------------------------------------
794 : 0 : sal_Bool OSQLParseTreeIterator::getColumnTableRange(const OSQLParseNode* pNode, ::rtl::OUString &rTableRange) const
795 : : {
796 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnTableRange" );
797 : : // See if all columns belong to one table
798 [ # # ][ # # ]: 0 : if (SQL_ISRULE(pNode,column_ref))
[ # # ]
799 : : {
800 : 0 : ::rtl::OUString aColName, aTableRange;
801 [ # # ]: 0 : getColumnRange(pNode, aColName, aTableRange);
802 [ # # ]: 0 : if (aTableRange.isEmpty()) // None found
803 : : {
804 : : // Look for the columns in the tables
805 [ # # ]: 0 : for (ConstOSQLTablesIterator aIter = m_pImpl->m_pTables->begin(); aIter != m_pImpl->m_pTables->end(); ++aIter)
806 : : {
807 [ # # ]: 0 : if (aIter->second.is())
808 : : {
809 : : try
810 : : {
811 [ # # ][ # # ]: 0 : Reference< XNameAccess > xColumns = aIter->second->getColumns();
812 [ # # ][ # # ]: 0 : if(xColumns->hasByName(aColName))
[ # # ]
813 : : {
814 : 0 : Reference< XPropertySet > xColumn;
815 [ # # ][ # # ]: 0 : if (xColumns->getByName(aColName) >>= xColumn)
[ # # ][ # # ]
816 : : {
817 : : OSL_ENSURE(xColumn.is(),"Column isn't a propertyset!");
818 : 0 : aTableRange = aIter->first;
819 : : break;
820 [ # # ]: 0 : }
821 [ # # ][ # # ]: 0 : }
822 : : }
823 [ # # ]: 0 : catch(Exception&)
824 : : {
825 : : }
826 : : }
827 : : }
828 [ # # ]: 0 : if (aTableRange.isEmpty())
829 : 0 : return sal_False;
830 : : }
831 : :
832 : :
833 [ # # ]: 0 : if (rTableRange.isEmpty())
834 : 0 : rTableRange = aTableRange;
835 [ # # ]: 0 : else if (rTableRange != aTableRange)
836 [ # # ][ # # ]: 0 : return sal_False;
837 : : }
838 : : else
839 : : {
840 [ # # ]: 0 : for (sal_uInt32 i = 0, ncount = pNode->count(); i < ncount; i++)
841 : : {
842 [ # # ]: 0 : if (!getColumnTableRange(pNode->getChild(i), rTableRange))
843 : 0 : return sal_False;
844 : : }
845 : : }
846 : 0 : return sal_True;
847 : : }
848 : :
849 : : //-----------------------------------------------------------------------------
850 : 0 : void OSQLParseTreeIterator::traverseCreateColumns(const OSQLParseNode* pSelectNode)
851 : : {
852 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseCreateColumns" );
853 : : // aIteratorStatus.Clear();
854 : :
855 [ # # ][ # # ]: 0 : if (!pSelectNode || m_eStatementType != SQL_STATEMENT_CREATE_TABLE || m_pImpl->m_pTables->empty())
[ # # ][ # # ]
856 : : {
857 : 0 : impl_appendError( IParseContext::ERROR_GENERAL );
858 : 0 : return;
859 : : }
860 [ # # ][ # # ]: 0 : if (!SQL_ISRULE(pSelectNode,base_table_element_commalist))
[ # # ]
861 : 0 : return ;
862 : :
863 [ # # ]: 0 : for (sal_uInt32 i = 0; i < pSelectNode->count(); i++)
864 : : {
865 : 0 : OSQLParseNode *pColumnRef = pSelectNode->getChild(i);
866 : :
867 [ # # ][ # # ]: 0 : if (SQL_ISRULE(pColumnRef,column_def))
[ # # ]
868 : : {
869 : 0 : ::rtl::OUString aColumnName;
870 : 0 : ::rtl::OUString aTypeName;
871 : 0 : ::rtl::OUString aTableRange;
872 : 0 : sal_Int32 nType = DataType::VARCHAR;
873 [ # # ]: 0 : aColumnName = pColumnRef->getChild(0)->getTokenValue();
874 : :
875 [ # # ]: 0 : OSQLParseNode *pDatatype = pColumnRef->getChild(1);
876 [ # # ][ # # ]: 0 : if (pDatatype && SQL_ISRULE(pDatatype,character_string_type))
[ # # ][ # # ]
[ # # ]
877 : : {
878 [ # # ]: 0 : const OSQLParseNode *pType = pDatatype->getChild(0);
879 : 0 : aTypeName = pType->getTokenValue();
880 [ # # ][ # # ]: 0 : if (pDatatype->count() == 2 && (pType->getTokenID() == SQL_TOKEN_CHAR || pType->getTokenID() == SQL_TOKEN_CHARACTER ))
[ # # ][ # # ]
881 : 0 : nType = DataType::CHAR;
882 : :
883 [ # # ]: 0 : const OSQLParseNode *pParams = pDatatype->getChild(pDatatype->count()-1);
884 [ # # ]: 0 : if ( pParams->count() )
885 : : {
886 [ # # ]: 0 : sal_Int32 nLen = pParams->getChild(1)->getTokenValue().toInt32();
887 : : (void)nLen;
888 : : }
889 : : }
890 [ # # ][ # # ]: 0 : else if(pDatatype && pDatatype->getNodeType() == SQL_NODE_KEYWORD)
[ # # ]
891 : : {
892 : 0 : aTypeName = ::rtl::OUString("VARCHAR");
893 : : }
894 : :
895 [ # # ]: 0 : if (!aTypeName.isEmpty())
896 : : {
897 : : //TODO:Create a new class for create statement to handle field length
898 : : OParseColumn* pColumn = new OParseColumn(aColumnName,aTypeName,::rtl::OUString(),::rtl::OUString(),
899 [ # # ][ # # ]: 0 : ColumnValue::NULLABLE_UNKNOWN,0,0,nType,sal_False,sal_False,isCaseSensitive());
900 : 0 : pColumn->setFunction(sal_False);
901 : 0 : pColumn->setRealName(aColumnName);
902 : :
903 [ # # ][ # # ]: 0 : Reference< XPropertySet> xCol = pColumn;
904 [ # # ]: 0 : m_aCreateColumns->get().push_back(xCol);
905 : 0 : }
906 : : }
907 : :
908 : : }
909 : : }
910 : : //-----------------------------------------------------------------------------
911 : 320 : bool OSQLParseTreeIterator::traverseSelectColumnNames(const OSQLParseNode* pSelectNode)
912 : : {
913 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseSelectColumnNames" );
914 [ - + ]: 320 : if ( ( m_pImpl->m_nIncludeMask & SelectColumns ) != SelectColumns )
915 : 0 : return true;
916 : :
917 [ + - ][ + - ]: 320 : if (!pSelectNode || m_eStatementType != SQL_STATEMENT_SELECT || m_pImpl->m_pTables->empty())
[ - + ][ - + ]
918 : : {
919 : 0 : impl_appendError( IParseContext::ERROR_GENERAL );
920 : 0 : return false;
921 : : }
922 : :
923 [ + - ][ - + ]: 320 : if(SQL_ISRULE(pSelectNode,union_statement))
[ - + ]
924 : : {
925 : 0 : return traverseSelectColumnNames( pSelectNode->getChild( 0 ) )
926 : : /*&& traverseSelectColumnNames( pSelectNode->getChild( 3 ) )*/;
927 : : }
928 : :
929 [ + + ][ + - ]: 320 : static ::rtl::OUString aEmptyString;
930 : : // nyi: more checks for correct structure!
931 [ + - ][ + + ]: 320 : if (pSelectNode->getChild(2)->isRule() && SQL_ISPUNCTUATION(pSelectNode->getChild(2)->getChild(0),"*"))
[ + - ][ + + ]
932 : : {
933 : : // SELECT * ...
934 [ + - ]: 140 : setSelectColumnName(m_aSelectColumns,::rtl::OUString("*"), aEmptyString,aEmptyString);
935 : : }
936 [ + - ][ + - ]: 180 : else if (SQL_ISRULE(pSelectNode->getChild(2),scalar_exp_commalist))
[ + - ]
937 : : {
938 : : // SELECT column[,column] oder SELECT COUNT(*) ...
939 : 180 : OSQLParseNode * pSelection = pSelectNode->getChild(2);
940 : :
941 [ + + ]: 568 : for (sal_uInt32 i = 0; i < pSelection->count(); i++)
942 : : {
943 : 388 : OSQLParseNode *pColumnRef = pSelection->getChild(i);
944 : :
945 : : //if (SQL_ISRULE(pColumnRef,select_sublist))
946 [ + - + - : 1552 : if (SQL_ISRULE(pColumnRef,derived_column) &&
+ - - + #
# # # ]
[ - + ][ + - ]
947 : 776 : SQL_ISRULE(pColumnRef->getChild(0),column_ref) &&
948 : 388 : pColumnRef->getChild(0)->count() == 3 &&
949 : 0 : SQL_ISPUNCTUATION(pColumnRef->getChild(0)->getChild(2),"*"))
950 : : {
951 : : // All the table's columns
952 : 0 : ::rtl::OUString aTableRange;
953 [ # # ][ # # ]: 0 : pColumnRef->getChild(0)->parseNodeToStr( aTableRange, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
954 [ # # ]: 0 : setSelectColumnName(m_aSelectColumns,::rtl::OUString("*"), aEmptyString,aTableRange);
955 : 0 : continue;
956 : : }
957 [ + - ][ + - ]: 388 : else if (SQL_ISRULE(pColumnRef,derived_column))
[ + - ]
958 : : {
959 [ + - ]: 388 : ::rtl::OUString aColumnAlias(getColumnAlias(pColumnRef)); // can be empty
960 : 388 : ::rtl::OUString sColumnName;
961 : 388 : ::rtl::OUString aTableRange;
962 : 388 : sal_Int32 nType = DataType::VARCHAR;
963 : 388 : sal_Bool bFkt(sal_False);
964 [ + - ]: 388 : pColumnRef = pColumnRef->getChild(0);
965 [ - + ][ - + : 388 : if (
# # # # #
# # # ]
966 : 388 : pColumnRef->count() == 3 &&
967 [ # # ][ # # ]: 0 : SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") &&
968 [ # # ][ # # ]: 0 : SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
969 : : )
970 [ # # ]: 0 : pColumnRef = pColumnRef->getChild(1);
971 : :
972 [ + - ][ + - ]: 388 : if (SQL_ISRULE(pColumnRef,column_ref))
[ + - ][ + - ]
973 : : {
974 [ + - ]: 388 : getColumnRange(pColumnRef,sColumnName,aTableRange);
975 : : OSL_ENSURE(!sColumnName.isEmpty(),"Column name must not be empty!");
976 : : }
977 : : else /*if (SQL_ISRULE(pColumnRef,general_set_fct) || SQL_ISRULE(pColumnRef,set_fct_spec) ||
978 : : SQL_ISRULE(pColumnRef,position_exp) || SQL_ISRULE(pColumnRef,extract_exp) ||
979 : : SQL_ISRULE(pColumnRef,length_exp) || SQL_ISRULE(pColumnRef,char_value_fct)||
980 : : SQL_ISRULE(pColumnRef,num_value_exp) || SQL_ISRULE(pColumnRef,term))*/
981 : : {
982 : : // Function call present
983 [ # # ]: 0 : pColumnRef->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_True );
984 : 0 : ::rtl::OUString sTableRange;
985 : : // check if the column is also a parameter
986 [ # # ]: 0 : traverseORCriteria(pColumnRef); // num_value_exp
987 : :
988 : : // Do all involved columns of the function belong to one table?
989 [ # # ]: 0 : if (m_pImpl->m_pTables->size() == 1)
990 : : {
991 : 0 : aTableRange = m_pImpl->m_pTables->begin()->first;
992 : : }
993 : : else
994 : : {
995 [ # # ]: 0 : getColumnTableRange(pColumnRef,aTableRange);
996 : : }
997 [ # # ]: 0 : if ( pColumnRef->isRule() )
998 : : {
999 : 0 : bFkt = sal_True;
1000 [ # # ]: 0 : nType = getFunctionReturnType(pColumnRef);
1001 : 0 : }
1002 : : }
1003 : : /*
1004 : : else
1005 : : {
1006 : : aIteratorStatus.setStatementTooComplex();
1007 : : return;
1008 : : }
1009 : : */
1010 [ + - ]: 388 : if(aColumnAlias.isEmpty())
1011 : 388 : aColumnAlias = sColumnName;
1012 [ + - ][ + - ]: 388 : setSelectColumnName(m_aSelectColumns,sColumnName,aColumnAlias,aTableRange,bFkt,nType,SQL_ISRULE(pColumnRef,general_set_fct) || SQL_ISRULE(pColumnRef,set_fct_spec));
[ + - ][ + - ]
[ + - ][ - + ]
[ + - ]
1013 : : }
1014 : : }
1015 : : }
1016 : :
1017 : 320 : return !hasErrors();
1018 : : }
1019 : :
1020 : :
1021 : : //-----------------------------------------------------------------------------
1022 : 320 : bool OSQLParseTreeIterator::traverseOrderByColumnNames(const OSQLParseNode* pSelectNode)
1023 : : {
1024 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseOrderByColumnNames" );
1025 : 320 : traverseByColumnNames( pSelectNode, sal_True );
1026 : 320 : return !hasErrors();
1027 : : }
1028 : : //-----------------------------------------------------------------------------
1029 : 640 : void OSQLParseTreeIterator::traverseByColumnNames(const OSQLParseNode* pSelectNode,sal_Bool _bOrder)
1030 : : {
1031 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseByColumnNames" );
1032 : : // aIteratorStatus.Clear();
1033 : :
1034 [ + - ]: 640 : if (pSelectNode == NULL)
1035 : : {
1036 : : //aIteratorStatus.setInvalidStatement();
1037 : : return;
1038 : : }
1039 : :
1040 [ + - ]: 640 : if (m_eStatementType != SQL_STATEMENT_SELECT)
1041 : : {
1042 : : //aIteratorStatus.setInvalidStatement();
1043 : : return;
1044 : : }
1045 : :
1046 [ + - ][ + - ]: 640 : if(SQL_ISRULE(pSelectNode,union_statement))
[ - + ][ - + ]
1047 : : {
1048 [ # # ][ # # ]: 0 : traverseByColumnNames(pSelectNode->getChild(0),_bOrder);
1049 : : return;
1050 : : }
1051 : :
1052 : : OSL_ENSURE(pSelectNode->count() >= 4,"OSQLParseTreeIterator: error in parse tree!");
1053 : :
1054 [ + - ]: 640 : OSQLParseNode * pTableExp = pSelectNode->getChild(3);
1055 : : OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!");
1056 : : OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator:table_exp error in parse tree!");
1057 : : OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!");
1058 : :
1059 [ + + ]: 640 : sal_uInt32 nPos = ( _bOrder ? ORDER_BY_CHILD_POS : 2 );
1060 : :
1061 [ + - ]: 640 : OSQLParseNode * pOptByClause = pTableExp->getChild(nPos);
1062 : : OSL_ENSURE(pOptByClause != NULL,"OSQLParseTreeIterator: error in parse tree!");
1063 [ + + ]: 640 : if ( pOptByClause->count() == 0 )
1064 : : return;
1065 : :
1066 : : OSL_ENSURE(pOptByClause->count() == 3,"OSQLParseTreeIterator: error in parse tree!");
1067 : :
1068 [ + - ]: 86 : OSQLParseNode * pOrderingSpecCommalist = pOptByClause->getChild(2);
1069 : : OSL_ENSURE(pOrderingSpecCommalist != NULL,"OSQLParseTreeIterator: error in parse tree!");
1070 : : OSL_ENSURE(!_bOrder || SQL_ISRULE(pOrderingSpecCommalist,ordering_spec_commalist),"OSQLParseTreeIterator:ordering_spec_commalist error in parse tree!");
1071 : : OSL_ENSURE(pOrderingSpecCommalist->count() > 0,"OSQLParseTreeIterator: error in parse tree!");
1072 : :
1073 : 86 : ::rtl::OUString sColumnName,aColumnAlias;
1074 : 86 : ::rtl::OUString aTableRange;
1075 : 86 : sal_uInt32 nCount = pOrderingSpecCommalist->count();
1076 [ + + ]: 172 : for (sal_uInt32 i = 0; i < nCount; ++i)
1077 : : {
1078 [ + - ]: 86 : OSQLParseNode* pColumnRef = pOrderingSpecCommalist->getChild(i);
1079 : : OSL_ENSURE(pColumnRef != NULL,"OSQLParseTreeIterator: error in parse tree!");
1080 [ + + ]: 86 : if ( _bOrder )
1081 : : {
1082 : : OSL_ENSURE(SQL_ISRULE(pColumnRef,ordering_spec),"OSQLParseTreeIterator:ordering_spec error in parse tree!");
1083 : : OSL_ENSURE(pColumnRef->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
1084 : :
1085 [ + - ]: 26 : pColumnRef = pColumnRef->getChild(0);
1086 : : }
1087 : 86 : aTableRange = ::rtl::OUString();
1088 : 86 : sColumnName = ::rtl::OUString();
1089 [ + - ][ + - ]: 86 : if ( SQL_ISRULE(pColumnRef,column_ref) )
[ + - ][ + - ]
1090 : : {
1091 : : // Column name (and TableRange):
1092 [ + - ][ + - ]: 86 : if(SQL_ISRULE(pColumnRef,column_ref))
[ + - ][ + - ]
1093 [ + - ]: 86 : getColumnRange(pColumnRef,sColumnName,aTableRange);
1094 : : else // an expression
1095 [ # # ]: 0 : pColumnRef->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
1096 : :
1097 : : OSL_ENSURE(!sColumnName.isEmpty(),"sColumnName must not be empty!");
1098 : : }
1099 : : else
1100 : : { // here I found a predicate
1101 [ # # ]: 0 : pColumnRef->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
1102 : : }
1103 : : OSL_ENSURE(pColumnRef != NULL,"OSQLParseTreeIterator: error in parse tree!");
1104 [ + + ]: 86 : if ( _bOrder )
1105 : : {
1106 : : // Ascending/Descending
1107 [ + - ]: 26 : OSQLParseNode * pOptAscDesc = pColumnRef->getParent()->getChild(1);
1108 : : OSL_ENSURE(pOptAscDesc != NULL,"OSQLParseTreeIterator: error in parse tree!");
1109 : :
1110 [ + - ][ - + ]: 26 : sal_Bool bAscending = pOptAscDesc && SQL_ISTOKEN(pOptAscDesc,ASC);
[ # # ]
1111 [ + - ]: 26 : setOrderByColumnName(sColumnName, aTableRange,bAscending);
1112 : : }
1113 : : else
1114 [ + - ]: 60 : setGroupByColumnName(sColumnName, aTableRange);
1115 : 640 : }
1116 : : }
1117 : : //-----------------------------------------------------------------------------
1118 : 320 : bool OSQLParseTreeIterator::traverseGroupByColumnNames(const OSQLParseNode* pSelectNode)
1119 : : {
1120 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseGroupByColumnNames" );
1121 : 320 : traverseByColumnNames( pSelectNode, sal_False );
1122 : 320 : return !hasErrors();
1123 : : }
1124 : :
1125 : : // -----------------------------------------------------------------------------
1126 : : namespace
1127 : : {
1128 : 794 : ::rtl::OUString lcl_generateParameterName( const OSQLParseNode& _rParentNode, const OSQLParseNode& _rParamNode )
1129 : : {
1130 : 794 : ::rtl::OUString sColumnName( "param" );
1131 : 794 : const sal_Int32 nCount = (sal_Int32)_rParentNode.count();
1132 [ + - ]: 1106 : for ( sal_Int32 i = 0; i < nCount; ++i )
1133 : : {
1134 [ + - ][ + + ]: 1106 : if ( _rParentNode.getChild(i) == &_rParamNode )
1135 : : {
1136 : 794 : sColumnName += ::rtl::OUString::valueOf( i+1 );
1137 : 794 : break;
1138 : : }
1139 : : }
1140 : 794 : return sColumnName;
1141 : : }
1142 : : }
1143 : :
1144 : : // -----------------------------------------------------------------------------
1145 : 20744 : void OSQLParseTreeIterator::traverseParameters(const OSQLParseNode* _pNode)
1146 : : {
1147 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseParameters" );
1148 [ + - ]: 20744 : if ( _pNode == NULL )
1149 : 20744 : return;
1150 : :
1151 : 20744 : ::rtl::OUString sColumnName, sTableRange, aColumnAlias;
1152 : 20744 : const OSQLParseNode* pParent = _pNode->getParent();
1153 [ + + ]: 20744 : if ( pParent != NULL )
1154 : : {
1155 [ + - ][ + - ]: 20424 : if ( SQL_ISRULE(pParent,comparison_predicate) ) // x = X
[ + + ][ + + ]
1156 : : {
1157 : 3438 : sal_uInt32 nPos = 0;
1158 [ + - ][ + + ]: 3438 : if ( pParent->getChild(nPos) == _pNode )
1159 : 1146 : nPos = 2;
1160 [ + - ]: 3438 : const OSQLParseNode* pOther = pParent->getChild(nPos);
1161 [ + + ][ + - ]: 3438 : if ( SQL_ISRULE( pOther, column_ref ) )
[ + + ][ + + ]
1162 [ + - ]: 2196 : getColumnRange( pOther, sColumnName, sTableRange, aColumnAlias);
1163 : : else
1164 [ + - ]: 1242 : pOther->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
1165 : : } // if ( SQL_ISRULE(pParent,comparison_predicate) ) // x = X
1166 [ + - ][ + - ]: 16986 : else if ( SQL_ISRULE(pParent,other_like_predicate_part_2) )
[ - + ][ - + ]
1167 : : {
1168 [ # # ]: 0 : const OSQLParseNode* pOther = pParent->getParent()->getChild(0);
1169 [ # # ][ # # ]: 0 : if ( SQL_ISRULE( pOther, column_ref ) )
[ # # ][ # # ]
1170 [ # # ]: 0 : getColumnRange( pOther, sColumnName, sTableRange, aColumnAlias);
1171 : : else
1172 [ # # ]: 0 : pOther->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
1173 : : }
1174 [ + - ][ + - ]: 16986 : else if ( SQL_ISRULE(pParent,between_predicate_part_2) )
[ - + ][ - + ]
1175 : : {
1176 [ # # ]: 0 : const OSQLParseNode* pOther = pParent->getParent()->getChild(0);
1177 [ # # ][ # # ]: 0 : if ( SQL_ISRULE( pOther, column_ref ) )
[ # # ][ # # ]
1178 [ # # ]: 0 : getColumnRange( pOther, sColumnName, sTableRange, aColumnAlias);
1179 : : else
1180 : : {
1181 [ # # ]: 0 : pOther->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
1182 [ # # ]: 0 : lcl_generateParameterName( *pParent, *_pNode );
1183 : : }
1184 : : }
1185 [ + + ]: 16986 : else if ( pParent->getNodeType() == SQL_NODE_COMMALISTRULE )
1186 : : {
1187 [ + - ]: 794 : lcl_generateParameterName( *pParent, *_pNode );
1188 : : }
1189 : : }
1190 [ + - ]: 20744 : traverseParameter( _pNode, pParent, sColumnName, sTableRange, aColumnAlias );
1191 : 20744 : const sal_uInt32 nCount = _pNode->count();
1192 [ + + ]: 41168 : for (sal_uInt32 i = 0; i < nCount; ++i)
1193 : : {
1194 [ + - ]: 20424 : const OSQLParseNode* pChild = _pNode->getChild(i);
1195 [ + - ]: 20424 : traverseParameters( pChild );
1196 : 20744 : }
1197 : : }
1198 : : //-----------------------------------------------------------------------------
1199 : 320 : bool OSQLParseTreeIterator::traverseSelectionCriteria(const OSQLParseNode* pSelectNode)
1200 : : {
1201 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseSelectionCriteria" );
1202 [ - + ]: 320 : if ( pSelectNode == NULL )
1203 : 0 : return false;
1204 : :
1205 : :
1206 : : // Analyse parse tree (depending on statement type)
1207 : : // and set pointer to WHERE clause:
1208 : 320 : OSQLParseNode * pWhereClause = NULL;
1209 : :
1210 [ + - ]: 320 : if (m_eStatementType == SQL_STATEMENT_SELECT)
1211 : : {
1212 [ + - ][ - + ]: 320 : if(SQL_ISRULE(pSelectNode,union_statement))
[ - + ]
1213 : : {
1214 : 0 : return traverseSelectionCriteria( pSelectNode->getChild( 0 ) )
1215 [ # # ][ # # ]: 0 : && traverseSelectionCriteria( pSelectNode->getChild( 3 ) );
1216 : : }
1217 : : OSL_ENSURE(pSelectNode->count() >= 4,"OSQLParseTreeIterator: error in parse tree!");
1218 : :
1219 : 320 : OSQLParseNode * pTableExp = pSelectNode->getChild(3);
1220 : : OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!");
1221 : : OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: error in parse tree!");
1222 : : OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!");
1223 : :
1224 : 320 : pWhereClause = pTableExp->getChild(1);
1225 [ # # ][ # # ]: 0 : } else if (SQL_ISRULE(pSelectNode,update_statement_searched)) {
[ # # ]
1226 : : OSL_ENSURE(pSelectNode->count() == 5,"OSQLParseTreeIterator: error in parse tree!");
1227 : 0 : pWhereClause = pSelectNode->getChild(4);
1228 [ # # ][ # # ]: 0 : } else if (SQL_ISRULE(pSelectNode,delete_statement_searched)) {
[ # # ]
1229 : : OSL_ENSURE(pSelectNode->count() == 4,"OSQLParseTreeIterator: error in parse tree!");
1230 : 0 : pWhereClause = pSelectNode->getChild(3);
1231 [ # # ][ # # ]: 0 : } else if (SQL_ISRULE(pSelectNode,delete_statement_positioned)) {
[ # # ]
1232 : : // nyi
1233 : : OSL_FAIL("OSQLParseTreeIterator::getSelectionCriteria: positioned nyi");
1234 : : } else {
1235 : : // Other statement, no selection criteria
1236 : 0 : return false;
1237 : : }
1238 : :
1239 [ + - ][ + + ]: 320 : if (! SQL_ISRULE(pWhereClause,where_clause)) {
[ + + ]
1240 : : // The WHERE clause is optional most of the time; which means it could be a "optional_where_clause".
1241 : : OSL_ENSURE(SQL_ISRULE(pWhereClause,opt_where_clause),"OSQLParseTreeIterator: error in parse tree!");
1242 : 154 : return false;
1243 : : }
1244 : :
1245 : : // But if it's a where_clause, then it must not be empty
1246 : : OSL_ENSURE(pWhereClause->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
1247 : :
1248 : 166 : OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1);
1249 : : OSL_ENSURE(pComparisonPredicate != NULL,"OSQLParseTreeIterator: error in parse tree!");
1250 : :
1251 : : //
1252 : : // Process the comparison criteria now (recursively, for a start everything is an OR criterion)
1253 : : //
1254 : :
1255 : 166 : traverseORCriteria(pComparisonPredicate);
1256 : :
1257 : 320 : return !hasErrors();
1258 : : }
1259 : :
1260 : : //-----------------------------------------------------------------------------
1261 : 1356 : void OSQLParseTreeIterator::traverseORCriteria(OSQLParseNode * pSearchCondition)
1262 : : {
1263 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseORCriteria" );
1264 : :
1265 : :
1266 [ + + ][ + + : 2126 : if (
+ + + - +
- + - ]
1267 : 1356 : pSearchCondition->count() == 3 &&
1268 : 594 : SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
1269 : 176 : SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")")
1270 : : )
1271 : : {
1272 : : // Round brackets around the expression
1273 : 88 : traverseORCriteria(pSearchCondition->getChild(1));
1274 [ + + ][ + + : 2264 : } else if (SQL_ISRULE(pSearchCondition,search_condition) &&
+ - + - +
- ][ + + ]
1275 : 332 : pSearchCondition->count() == 3 &&
1276 : 664 : SQL_ISTOKEN(pSearchCondition->getChild(1),OR))
1277 : : {
1278 : : // OR logic operation
1279 [ + + ]: 1328 : for (int i = 0; i < 3; i++) {
1280 [ + + ]: 996 : if (i == 1) continue; // Skip OR keyword
1281 : :
1282 : : // Is the first element an OR again?
1283 [ + + + - : 1952 : if (i == 0 &&
+ + + - +
- + - ]
[ + + ]
1284 : 664 : SQL_ISRULE(pSearchCondition->getChild(0),search_condition) &&
1285 : 208 : pSearchCondition->getChild(0)->count() == 3 &&
1286 : 416 : SQL_ISTOKEN(pSearchCondition->getChild(0)->getChild(1),OR))
1287 : : {
1288 : : // Then process recursively
1289 : 208 : traverseORCriteria(pSearchCondition->getChild(0));
1290 : :
1291 : : } else {
1292 : : // AND criteria
1293 : 456 : traverseANDCriteria(pSearchCondition->getChild(i));
1294 : : // if (! aIteratorStatus.IsSuccessful()) break;
1295 : : }
1296 : :
1297 : : // if (! aIteratorStatus.IsSuccessful()) break;
1298 : : }
1299 : : } else {
1300 : : // Only *one* criterion or one AND logical operation of criteria
1301 : : // Process the AND criteria directly
1302 : 936 : traverseANDCriteria(pSearchCondition);
1303 : : // if (! aIteratorStatus.IsSuccessful()) return;
1304 : : }
1305 : :
1306 : : // Just pass on the error
1307 : 1356 : }
1308 : :
1309 : : //-----------------------------------------------------------------------------
1310 : 2772 : void OSQLParseTreeIterator::traverseANDCriteria(OSQLParseNode * pSearchCondition)
1311 : : {
1312 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseANDCriteria" );
1313 : :
1314 : :
1315 [ + + ][ + + : 7492 : if (
+ + + - +
- + - + -
+ - ]
1316 : 4732 : SQL_ISRULE(pSearchCondition,boolean_primary) &&
1317 : 552 : pSearchCondition->count() == 3 &&
1318 : 1104 : SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") &&
1319 : 1104 : SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")")
1320 : : )
1321 : : {
1322 : : // Round brackets
1323 : 552 : traverseANDCriteria(pSearchCondition->getChild(1));
1324 : : }
1325 : : // The first element is an OR logical operation
1326 [ + + ][ + + ]: 2220 : else if ( SQL_ISRULE(pSearchCondition,search_condition) && pSearchCondition->count() == 3 )
[ + - ][ + + ]
1327 : : {
1328 : : // Then process recursively (use the same row) ...
1329 : 44 : traverseORCriteria(pSearchCondition->getChild(0));
1330 : : // if (! aIteratorStatus.IsSuccessful())
1331 : : // return;
1332 : :
1333 : : // Continue with the right child
1334 : 44 : traverseANDCriteria(pSearchCondition->getChild(2));
1335 : : }
1336 : : // The first element is an AND logical operation (again)
1337 [ + + ][ + + ]: 2176 : else if ( SQL_ISRULE(pSearchCondition,boolean_term) && pSearchCondition->count() == 3 )
[ + - ][ + + ]
1338 : : {
1339 : : // Then process recursively (use the same row)
1340 : 392 : traverseANDCriteria(pSearchCondition->getChild(0));
1341 : : // if (! aIteratorStatus.IsSuccessful())
1342 : : // return;
1343 : :
1344 : : // Continue with the right child
1345 : 392 : traverseANDCriteria(pSearchCondition->getChild(2));
1346 : : }
1347 : : // Else, process single search criteria (like =, !=, ..., LIKE, IS NULL etc.)
1348 [ + + ][ + + ]: 1784 : else if (SQL_ISRULE(pSearchCondition,comparison_predicate) )
[ + + ]
1349 : : {
1350 : 850 : ::rtl::OUString aValue;
1351 [ + - ][ + - ]: 850 : pSearchCondition->getChild(2)->parseNodeToStr( aValue, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
1352 [ + - ][ + - ]: 850 : traverseOnePredicate(pSearchCondition->getChild(0),aValue,pSearchCondition->getChild(2));
[ + - ]
1353 [ + - ]: 850 : impl_fillJoinConditions(pSearchCondition);
1354 : : // if (! aIteratorStatus.IsSuccessful())
1355 : : // return;
1356 : : }
1357 [ + + ][ - + ]: 934 : else if (SQL_ISRULE(pSearchCondition,like_predicate) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/)
[ - + ]
1358 : : {
1359 : : OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
1360 [ # # ]: 0 : const OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
1361 : :
1362 : 0 : sal_Int32 nCurentPos = pPart2->count()-2;
1363 : :
1364 [ # # ]: 0 : OSQLParseNode * pNum_value_exp = pPart2->getChild(nCurentPos);
1365 [ # # ]: 0 : OSQLParseNode * pOptEscape = pPart2->getChild(nCurentPos+1);
1366 : :
1367 : : OSL_ENSURE(pNum_value_exp != NULL,"OSQLParseTreeIterator: error in parse tree!");
1368 : : OSL_ENSURE(pOptEscape != NULL,"OSQLParseTreeIterator: error in parse tree!");
1369 : :
1370 [ # # ]: 0 : if (pOptEscape->count() != 0)
1371 : : {
1372 : : // aIteratorStatus.setStatementTooComplex();
1373 : 2772 : return;
1374 : : }
1375 : :
1376 : 0 : ::rtl::OUString aValue;
1377 : 0 : OSQLParseNode * pParam = NULL;
1378 [ # # ][ # # ]: 0 : if (SQL_ISRULE(pNum_value_exp,parameter))
[ # # ][ # # ]
1379 : 0 : pParam = pNum_value_exp;
1380 [ # # ]: 0 : else if(pNum_value_exp->isToken())
1381 : : // Normal value
1382 : 0 : aValue = pNum_value_exp->getTokenValue();
1383 : : else
1384 : : {
1385 [ # # ]: 0 : pNum_value_exp->parseNodeToStr( aValue, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
1386 : 0 : pParam = pNum_value_exp;
1387 : : }
1388 : :
1389 [ # # ][ # # ]: 0 : traverseOnePredicate(pSearchCondition->getChild(0),aValue,pParam);
1390 : : // if (! aIteratorStatus.IsSuccessful())
1391 : : // return;
1392 : : }
1393 [ + + ][ - + ]: 934 : else if (SQL_ISRULE(pSearchCondition,in_predicate))
[ - + ]
1394 : : {
1395 : : OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
1396 : 0 : const OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
1397 : :
1398 : 0 : traverseORCriteria(pSearchCondition->getChild(0));
1399 : : // if (! aIteratorStatus.IsSuccessful()) return;
1400 : :
1401 : 0 : OSQLParseNode* pChild = pPart2->getChild(2);
1402 [ # # ][ # # ]: 0 : if ( SQL_ISRULE(pChild->getChild(0),subquery) )
[ # # ]
1403 : : {
1404 : 0 : traverseTableNames( *m_pImpl->m_pSubTables );
1405 : 0 : traverseSelectionCriteria(pChild->getChild(0)->getChild(1));
1406 : : }
1407 : : else
1408 : : { // '(' value_exp_commalist ')'
1409 : 0 : pChild = pChild->getChild(1);
1410 : 0 : sal_Int32 nCount = pChild->count();
1411 [ # # ]: 0 : for (sal_Int32 i=0; i < nCount; ++i)
1412 : : {
1413 : 0 : traverseANDCriteria(pChild->getChild(i));
1414 : : }
1415 : : }
1416 : : }
1417 [ + + ][ + + ]: 934 : else if (SQL_ISRULE(pSearchCondition,test_for_null) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/)
[ + + ]
1418 : : {
1419 : : OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
1420 [ + - ]: 84 : const OSQLParseNode* pPart2 = pSearchCondition->getChild(1);
1421 : : (void)pPart2;
1422 : : OSL_ENSURE(SQL_ISTOKEN(pPart2->getChild(0),IS),"OSQLParseTreeIterator: error in parse tree!");
1423 : :
1424 : 84 : ::rtl::OUString aString;
1425 [ + - ][ + - ]: 84 : traverseOnePredicate(pSearchCondition->getChild(0),aString,NULL);
1426 : : // if (! aIteratorStatus.IsSuccessful()) return;
1427 : : }
1428 [ + + ][ + - ]: 850 : else if (SQL_ISRULE(pSearchCondition,num_value_exp) || SQL_ISRULE(pSearchCondition,term))
[ + + ][ - + ]
[ - + ]
1429 : : {
1430 : 0 : ::rtl::OUString aString;
1431 [ # # ][ # # ]: 0 : traverseOnePredicate(pSearchCondition->getChild(0),aString,pSearchCondition->getChild(0));
[ # # ]
1432 [ # # ][ # # ]: 0 : traverseOnePredicate(pSearchCondition->getChild(2),aString,pSearchCondition->getChild(2));
[ # # ]
1433 : : }
1434 : : // Just pass on the error
1435 : : }
1436 : : //-----------------------------------------------------------------------------
1437 : 20744 : void OSQLParseTreeIterator::traverseParameter(const OSQLParseNode* _pParseNode
1438 : : ,const OSQLParseNode* _pParentNode
1439 : : ,const ::rtl::OUString& _aColumnName
1440 : : ,const ::rtl::OUString& _aTableRange
1441 : : ,const ::rtl::OUString& _rColumnAlias)
1442 : : {
1443 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseParameter" );
1444 [ + + ][ + - ]: 20744 : if ( !SQL_ISRULE( _pParseNode, parameter ) )
[ + + ][ + + ]
1445 : : return;
1446 : :
1447 [ + - ]: 38 : if ( ( m_pImpl->m_nIncludeMask & Parameters ) != Parameters )
1448 : : // parameters not to be included in the traversal
1449 : : return;
1450 : :
1451 : : OSL_ENSURE(_pParseNode->count() > 0,"OSQLParseTreeIterator: error in parse tree!");
1452 [ + - ]: 38 : OSQLParseNode * pMark = _pParseNode->getChild(0);
1453 : 38 : ::rtl::OUString sParameterName;
1454 : :
1455 [ - + ][ - + ]: 38 : if (SQL_ISPUNCTUATION(pMark,"?"))
[ + - ]
1456 : : {
1457 : 0 : sParameterName = !_rColumnAlias.isEmpty()
1458 : : ? _rColumnAlias
1459 : 0 : : !_aColumnName.isEmpty()
1460 : : ? _aColumnName
1461 [ # # ][ # # ]: 0 : : ::rtl::OUString("?");
[ # # ]
1462 : : }
1463 [ + - ][ + - ]: 38 : else if (SQL_ISPUNCTUATION(pMark,":"))
[ + - ]
1464 : : {
1465 [ + - ]: 38 : sParameterName = _pParseNode->getChild(1)->getTokenValue();
1466 : : }
1467 [ # # ][ # # ]: 0 : else if (SQL_ISPUNCTUATION(pMark,"["))
[ # # ]
1468 : : {
1469 [ # # ]: 0 : sParameterName = _pParseNode->getChild(1)->getTokenValue();
1470 : : }
1471 : : else
1472 : : {
1473 : : OSL_FAIL("OSQLParseTreeIterator: error in parse tree!");
1474 : : }
1475 : :
1476 : : // found a parameter
1477 [ + - ][ + - ]: 38 : if ( _pParentNode && (SQL_ISRULE(_pParentNode,general_set_fct) || SQL_ISRULE(_pParentNode,set_fct_spec)) )
[ + - ][ + - ]
[ + - ][ + - ]
[ - + ][ - + ]
1478 : : {// found a function as column_ref
1479 : 0 : ::rtl::OUString sFunctionName;
1480 [ # # ][ # # ]: 0 : _pParentNode->getChild(0)->parseNodeToStr( sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
1481 : 0 : const sal_uInt32 nCount = _pParentNode->count();
1482 : 0 : sal_uInt32 i = 0;
1483 [ # # ]: 0 : for(; i < nCount;++i)
1484 : : {
1485 [ # # ][ # # ]: 0 : if ( _pParentNode->getChild(i) == _pParseNode )
1486 : 0 : break;
1487 : : }
1488 [ # # ][ # # ]: 0 : sal_Int32 nType = ::connectivity::OSQLParser::getFunctionParameterType( _pParentNode->getChild(0)->getTokenID(), i-1);
1489 : :
1490 : : OParseColumn* pColumn = new OParseColumn( sParameterName,
1491 : : ::rtl::OUString(),
1492 : : ::rtl::OUString(),
1493 : : ::rtl::OUString(),
1494 : : ColumnValue::NULLABLE_UNKNOWN,
1495 : : 0,
1496 : : 0,
1497 : : nType,
1498 : : sal_False,
1499 : : sal_False,
1500 [ # # ][ # # ]: 0 : isCaseSensitive());
1501 : 0 : pColumn->setFunction(sal_True);
1502 : 0 : pColumn->setAggregateFunction(sal_True);
1503 : 0 : pColumn->setRealName(sFunctionName);
1504 [ # # ][ # # ]: 0 : m_aParameters->get().push_back(pColumn);
[ # # ]
1505 : : }
1506 : : else
1507 : : {
1508 : 38 : sal_Bool bNotFound = sal_True;
1509 : : OSQLColumns::Vector::const_iterator aIter = ::connectivity::find(
1510 : 38 : m_aSelectColumns->get().begin(),
1511 : 38 : m_aSelectColumns->get().end(),
1512 [ + - ]: 38 : _aColumnName,::comphelper::UStringMixEqual( isCaseSensitive() )
1513 [ + - + - ]: 114 : );
[ + - ]
1514 [ + - ][ - + ]: 38 : if(aIter != m_aSelectColumns->get().end())
1515 : : {
1516 [ # # ][ # # ]: 0 : OParseColumn* pNewColumn = new OParseColumn(*aIter,isCaseSensitive());
1517 [ # # ]: 0 : pNewColumn->setName(sParameterName);
1518 : 0 : pNewColumn->setRealName(_aColumnName);
1519 [ # # ][ # # ]: 0 : m_aParameters->get().push_back(pNewColumn);
[ # # ]
1520 : 0 : bNotFound = sal_False;
1521 : : }
1522 [ + - ]: 38 : else if(!_aColumnName.isEmpty())// search in the tables for the right one
1523 : : {
1524 : :
1525 [ + - ]: 38 : Reference<XPropertySet> xColumn = findColumn( _aColumnName, _aTableRange, true );
1526 : :
1527 [ + - ]: 38 : if ( xColumn.is() )
1528 : : {
1529 [ + - ][ + - ]: 38 : OParseColumn* pNewColumn = new OParseColumn(xColumn,isCaseSensitive());
1530 [ + - ]: 38 : pNewColumn->setName(sParameterName);
1531 : 38 : pNewColumn->setRealName(_aColumnName);
1532 [ + - ][ + - ]: 38 : m_aParameters->get().push_back(pNewColumn);
[ + - ]
1533 : 38 : bNotFound = sal_False;
1534 : 38 : }
1535 : : }
1536 [ - + ]: 38 : if ( bNotFound )
1537 : : {
1538 : 0 : sal_Int32 nType = DataType::VARCHAR;
1539 [ # # ]: 0 : OSQLParseNode* pParent = _pParentNode ? _pParentNode->getParent() : NULL;
1540 [ # # ][ # # ]: 0 : if ( pParent && (SQL_ISRULE(pParent,general_set_fct) || SQL_ISRULE(pParent,set_fct_spec)) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
1541 : : {
1542 : 0 : const sal_uInt32 nCount = _pParentNode->count();
1543 : 0 : sal_uInt32 i = 0;
1544 [ # # ]: 0 : for(; i < nCount;++i)
1545 : : {
1546 [ # # ][ # # ]: 0 : if ( _pParentNode->getChild(i) == _pParseNode )
1547 : 0 : break;
1548 : : }
1549 [ # # ][ # # ]: 0 : nType = ::connectivity::OSQLParser::getFunctionParameterType( pParent->getChild(0)->getTokenID(), i+1);
1550 : : }
1551 : :
1552 [ # # ]: 0 : ::rtl::OUString aNewColName( getUniqueColumnName( sParameterName ) );
1553 : :
1554 : : OParseColumn* pColumn = new OParseColumn(aNewColName,
1555 : : ::rtl::OUString(),
1556 : : ::rtl::OUString(),
1557 : : ::rtl::OUString(),
1558 : : ColumnValue::NULLABLE_UNKNOWN,
1559 : : 0,
1560 : : 0,
1561 : : nType,
1562 : : sal_False,
1563 : : sal_False,
1564 [ # # ][ # # ]: 0 : isCaseSensitive() );
1565 [ # # ]: 0 : pColumn->setName(aNewColName);
1566 : 0 : pColumn->setRealName(sParameterName);
1567 [ # # ][ # # ]: 38 : m_aParameters->get().push_back(pColumn);
[ # # ]
1568 : : }
1569 : 20744 : }
1570 : : }
1571 : : //-----------------------------------------------------------------------------
1572 : 934 : void OSQLParseTreeIterator::traverseOnePredicate(
1573 : : OSQLParseNode * pColumnRef,
1574 : : ::rtl::OUString& rValue,
1575 : : OSQLParseNode * pParseNode)
1576 : : {
1577 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseOnePredicate" );
1578 [ + + ]: 934 : if ( !pParseNode )
1579 : 934 : return;
1580 : :
1581 : : // Column name (and TableRange):
1582 : 850 : ::rtl::OUString aColumnName, aTableRange, sColumnAlias;
1583 [ + - ]: 850 : getColumnRange( pColumnRef, aColumnName, aTableRange, sColumnAlias);
1584 : :
1585 : 850 : ::rtl::OUString aName;
1586 : :
1587 : : /*if (SQL_ISRULE(pParseNode,parameter))
1588 : : traverseParameter( pParseNode, pColumnRef, aColumnName, aTableRange, sColumnAlias );
1589 [ + - ][ - + ]: 850 : else */if (SQL_ISRULE(pParseNode,column_ref))// Column-Name (und TableRange):
[ - + ][ + + ]
1590 [ # # ]: 0 : getColumnRange(pParseNode,aName,rValue);
1591 : : else
1592 : : {
1593 [ + - ]: 850 : traverseORCriteria(pParseNode);
1594 : : // if (! aIteratorStatus.IsSuccessful()) return;
1595 : 934 : }
1596 : : }
1597 : :
1598 : : //-----------------------------------------------------------------------------
1599 : 0 : void OSQLParseTreeIterator::traverseSome( sal_uInt32 _nIncludeMask )
1600 : : {
1601 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseSome" );
1602 : 0 : impl_traverse( _nIncludeMask );
1603 : 0 : }
1604 : :
1605 : : //-----------------------------------------------------------------------------
1606 : 408 : void OSQLParseTreeIterator::traverseAll()
1607 : : {
1608 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseAll" );
1609 : 408 : impl_traverse( All );
1610 : 408 : }
1611 : :
1612 : : //-----------------------------------------------------------------------------
1613 : 408 : void OSQLParseTreeIterator::impl_traverse( sal_uInt32 _nIncludeMask )
1614 : : {
1615 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_traverse" );
1616 : 408 : impl_resetErrors();
1617 : 408 : m_pImpl->m_nIncludeMask = _nIncludeMask;
1618 : :
1619 [ + + ]: 408 : if ( !traverseTableNames( *m_pImpl->m_pTables ) )
1620 : 88 : return;
1621 : :
1622 [ + - - - ]: 320 : switch ( m_eStatementType )
1623 : : {
1624 : : case SQL_STATEMENT_SELECT:
1625 : : {
1626 : 320 : const OSQLParseNode* pSelectNode = m_pParseTree;
1627 : 320 : traverseParameters( pSelectNode );
1628 [ + + ][ + - : 1280 : if ( !traverseSelectColumnNames( pSelectNode )
+ - + - +
+ ]
1629 : 320 : || !traverseOrderByColumnNames( pSelectNode )
1630 : 320 : || !traverseGroupByColumnNames( pSelectNode )
1631 : 320 : || !traverseSelectionCriteria( pSelectNode )
1632 : : )
1633 : 154 : return;
1634 : : }
1635 : 166 : break;
1636 : : case SQL_STATEMENT_CREATE_TABLE:
1637 : : {
1638 : : //0 | 1 | 2 |3| 4 |5
1639 : : //create table sc.foo ( a char(20), b char )
1640 : 0 : const OSQLParseNode* pCreateNode = m_pParseTree->getChild(4);
1641 : 0 : traverseCreateColumns(pCreateNode);
1642 : : }
1643 : 0 : break;
1644 : : case SQL_STATEMENT_INSERT:
1645 : 0 : break;
1646 : : default:
1647 : 408 : break;
1648 : : }
1649 : : }
1650 : :
1651 : : // Dummy implementations
1652 : :
1653 : : //-----------------------------------------------------------------------------
1654 : 0 : OSQLTable OSQLParseTreeIterator::impl_createTableObject( const ::rtl::OUString& rTableName,
1655 : : const ::rtl::OUString& rCatalogName, const ::rtl::OUString& rSchemaName )
1656 : : {
1657 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_createTableObject" );
1658 : : OSL_PRECOND( m_eStatementType == SQL_STATEMENT_CREATE_TABLE,
1659 : : "OSQLParseTreeIterator::impl_createTableObject: only to be called for CREATE TABLE statements!" );
1660 : : // (in all other cases, m_pTables is to contain the table objects as obtained from the tables
1661 : : // container of the connection (m_xTablesContainer)
1662 : :
1663 : : OSQLTable aReturnTable = new OTable(
1664 : : NULL,
1665 : : sal_False,
1666 : : rTableName,
1667 : : ::rtl::OUString("Table"),
1668 : : ::rtl::OUString("New Created Table"),
1669 : : rSchemaName,
1670 : : rCatalogName
1671 [ # # ][ # # ]: 0 : );
[ # # ]
1672 : 0 : return aReturnTable;
1673 : : }
1674 : : //-----------------------------------------------------------------------------
1675 : 140 : void OSQLParseTreeIterator::appendColumns(::rtl::Reference<OSQLColumns>& _rColumns,const ::rtl::OUString& _rTableAlias,const OSQLTable& _rTable)
1676 : : {
1677 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::appendColumns" );
1678 : :
1679 [ + - ]: 140 : if (!_rTable.is())
1680 : : return;
1681 : :
1682 [ + - ][ + - ]: 140 : Reference<XNameAccess> xColumns = _rTable->getColumns();
1683 [ - + ]: 140 : if ( !xColumns.is() )
1684 : : return;
1685 : :
1686 [ + - ][ + - ]: 140 : Sequence< ::rtl::OUString > aColNames = xColumns->getElementNames();
1687 : 140 : const ::rtl::OUString* pBegin = aColNames.getConstArray();
1688 : 140 : const ::rtl::OUString* pEnd = pBegin + aColNames.getLength();
1689 : :
1690 [ + + ]: 3200 : for(;pBegin != pEnd;++pBegin)
1691 : : {
1692 : :
1693 [ + - ]: 3060 : ::rtl::OUString aName(getUniqueColumnName(*pBegin));
1694 : 3060 : Reference< XPropertySet > xColumn;
1695 [ + - ][ + - ]: 3060 : if(xColumns->hasByName(*pBegin) && (xColumns->getByName(*pBegin) >>= xColumn) && xColumn.is())
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - # # ]
[ + - ]
1696 : : {
1697 : : OParseColumn* pColumn = new OParseColumn(aName
1698 [ + - ][ + - ]: 3060 : , getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME)))
1699 [ + - ][ + - ]: 3060 : , getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE)))
1700 [ + - ][ + - ]: 3060 : , getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DESCRIPTION)))
1701 [ + - ][ + - ]: 6120 : , getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE)))
[ + - ][ + - ]
1702 [ + - ][ + - ]: 6120 : , getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION)))
[ + - ][ + - ]
1703 [ + - ][ + - ]: 6120 : , getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)))
[ + - ][ + - ]
1704 [ + - ][ + - ]: 6120 : , getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)))
[ + - ][ + - ]
1705 [ + - ][ + - ]: 6120 : , getBOOL(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)))
[ + - ][ + - ]
[ + - ]
1706 [ + - ][ + - ]: 6120 : , getBOOL(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY)))
[ + - ][ + - ]
[ + - ]
1707 [ + - ][ + - ]: 27540 : , isCaseSensitive() );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
1708 : :
1709 : 3060 : pColumn->setTableName(_rTableAlias);
1710 : 3060 : pColumn->setRealName(*pBegin);
1711 [ + - ][ + - ]: 3060 : Reference< XPropertySet> xCol = pColumn;
1712 [ + - ]: 3060 : _rColumns->get().push_back(xCol);
1713 : : }
1714 : : else
1715 [ # # ]: 0 : impl_appendError( IParseContext::ERROR_INVALID_COLUMN, pBegin, &_rTableAlias );
1716 [ + - ][ + - ]: 3200 : }
1717 : : }
1718 : : //-----------------------------------------------------------------------------
1719 : 528 : void OSQLParseTreeIterator::setSelectColumnName(::rtl::Reference<OSQLColumns>& _rColumns,const ::rtl::OUString & rColumnName,const ::rtl::OUString & rColumnAlias, const ::rtl::OUString & rTableRange,sal_Bool bFkt,sal_Int32 _nType,sal_Bool bAggFkt)
1720 : : {
1721 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setSelectColumnName" );
1722 [ + + ][ + - ]: 528 : if(rColumnName.toChar() == '*' && rTableRange.isEmpty())
[ + + ]
1723 : : { // SELECT * ...
1724 : : OSL_ENSURE(_rColumns == m_aSelectColumns,"Invalid columns used here!");
1725 [ + + ]: 280 : for(ConstOSQLTablesIterator aIter = m_pImpl->m_pTables->begin(); aIter != m_pImpl->m_pTables->end();++aIter)
1726 [ + - ]: 140 : appendColumns(_rColumns,aIter->first,aIter->second);
1727 : : }
1728 [ - + ][ # # ]: 388 : else if( rColumnName.toChar() == '*' && !rTableRange.isEmpty() )
[ - + ]
1729 : : { // SELECT <table>.*
1730 : : OSL_ENSURE(_rColumns == m_aSelectColumns,"Invalid columns used here!");
1731 [ # # ]: 0 : ConstOSQLTablesIterator aFind = m_pImpl->m_pTables->find(rTableRange);
1732 : :
1733 [ # # ]: 0 : if(aFind != m_pImpl->m_pTables->end())
1734 [ # # ]: 0 : appendColumns(_rColumns,rTableRange,aFind->second);
1735 : : }
1736 [ + - ]: 388 : else if ( rTableRange.isEmpty() )
1737 : : { // SELECT <something> ...
1738 : : // without table specified
1739 [ + - ]: 388 : if ( !bFkt )
1740 : : {
1741 : 388 : Reference< XPropertySet> xNewColumn;
1742 : :
1743 [ + - ]: 776 : for ( OSQLTablesIterator aIter = m_pImpl->m_pTables->begin(); aIter != m_pImpl->m_pTables->end(); ++aIter )
1744 : : {
1745 [ - + ]: 388 : if ( !aIter->second.is() )
1746 : 0 : continue;
1747 : :
1748 [ + - ][ + - ]: 388 : Reference<XNameAccess> xColumns = aIter->second->getColumns();
1749 : 388 : Reference< XPropertySet > xColumn;
1750 [ + - ][ + - ]: 1164 : if ( !xColumns->hasByName( rColumnName )
[ - + ][ - + ]
[ + - ]
1751 [ + - ][ + - ]: 776 : || !( xColumns->getByName( rColumnName ) >>= xColumn )
[ + - ][ + - ]
[ # # ]
1752 : : )
1753 : 0 : continue;
1754 : :
1755 [ + - ]: 388 : ::rtl::OUString aNewColName(getUniqueColumnName(rColumnAlias));
1756 : :
1757 [ + - ][ + - ]: 388 : OParseColumn* pColumn = new OParseColumn(xColumn,isCaseSensitive());
1758 [ + - ][ + - ]: 388 : xNewColumn = pColumn;
1759 : 388 : pColumn->setTableName(aIter->first);
1760 [ + - ]: 388 : pColumn->setName(aNewColName);
1761 : 388 : pColumn->setRealName(rColumnName);
1762 : :
1763 : : break;
1764 [ - + ][ - + ]: 388 : }
1765 : :
1766 [ - + ]: 388 : if ( !xNewColumn.is() )
1767 : : {
1768 : : // no function (due to the above !bFkt), no existing column
1769 : : // => assume an expression
1770 [ # # ]: 0 : ::rtl::OUString aNewColName( getUniqueColumnName( rColumnAlias ) );
1771 : : // did not find a column with this name in any of the tables
1772 : : OParseColumn* pColumn = new OParseColumn(
1773 : : aNewColName,
1774 : : ::rtl::OUString("VARCHAR"),
1775 : : // TODO: does this match with _nType?
1776 : : // Or should be fill this from the getTypeInfo of the connection?
1777 : : ::rtl::OUString(),
1778 : : ::rtl::OUString(),
1779 : : ColumnValue::NULLABLE_UNKNOWN,
1780 : : 0,
1781 : : 0,
1782 : : _nType,
1783 : : sal_False,
1784 : : sal_False,
1785 [ # # ]: 0 : isCaseSensitive()
1786 [ # # ]: 0 : );
1787 : :
1788 [ # # ][ # # ]: 0 : xNewColumn = pColumn;
1789 : 0 : pColumn->setRealName( rColumnName );
1790 : : }
1791 : :
1792 [ + - ]: 388 : _rColumns->get().push_back( xNewColumn );
1793 : : }
1794 : : else
1795 : : {
1796 [ # # ]: 0 : ::rtl::OUString aNewColName(getUniqueColumnName(rColumnAlias));
1797 : :
1798 : : OParseColumn* pColumn = new OParseColumn(aNewColName,::rtl::OUString(),::rtl::OUString(),::rtl::OUString(),
1799 [ # # ][ # # ]: 0 : ColumnValue::NULLABLE_UNKNOWN,0,0,_nType,sal_False,sal_False,isCaseSensitive());
1800 : 0 : pColumn->setFunction(sal_True);
1801 : 0 : pColumn->setAggregateFunction(bAggFkt);
1802 : 0 : pColumn->setRealName(rColumnName);
1803 : :
1804 [ # # ][ # # ]: 0 : Reference< XPropertySet> xCol = pColumn;
1805 [ # # ]: 0 : _rColumns->get().push_back(xCol);
1806 : : }
1807 : : }
1808 : : else // ColumnName and TableName exist
1809 : : {
1810 [ # # ]: 0 : ConstOSQLTablesIterator aFind = m_pImpl->m_pTables->find(rTableRange);
1811 : :
1812 : 0 : sal_Bool bError = sal_False;
1813 [ # # ][ # # ]: 0 : if (aFind != m_pImpl->m_pTables->end() && aFind->second.is())
[ # # ][ # # ]
[ # # ]
1814 : : {
1815 [ # # ]: 0 : if (bFkt)
1816 : : {
1817 [ # # ]: 0 : ::rtl::OUString aNewColName(getUniqueColumnName(rColumnAlias));
1818 : :
1819 : : OParseColumn* pColumn = new OParseColumn(aNewColName,::rtl::OUString(),::rtl::OUString(),::rtl::OUString(),
1820 [ # # ][ # # ]: 0 : ColumnValue::NULLABLE_UNKNOWN,0,0,_nType,sal_False,sal_False,isCaseSensitive());
1821 : 0 : pColumn->setFunction(sal_True);
1822 : 0 : pColumn->setAggregateFunction(bAggFkt);
1823 : 0 : pColumn->setRealName(rColumnName);
1824 : 0 : pColumn->setTableName(aFind->first);
1825 : :
1826 [ # # ][ # # ]: 0 : Reference< XPropertySet> xCol = pColumn;
1827 [ # # ]: 0 : _rColumns->get().push_back(xCol);
1828 : : }
1829 : : else
1830 : : {
1831 : 0 : Reference< XPropertySet > xColumn;
1832 [ # # ][ # # ]: 0 : if (aFind->second->getColumns()->hasByName(rColumnName) && (aFind->second->getColumns()->getByName(rColumnName) >>= xColumn))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# ][ # # ]
1833 : : {
1834 [ # # ]: 0 : ::rtl::OUString aNewColName(getUniqueColumnName(rColumnAlias));
1835 : :
1836 [ # # ][ # # ]: 0 : OParseColumn* pColumn = new OParseColumn(xColumn,isCaseSensitive());
1837 [ # # ]: 0 : pColumn->setName(aNewColName);
1838 : 0 : pColumn->setRealName(rColumnName);
1839 : 0 : pColumn->setTableName(aFind->first);
1840 : :
1841 [ # # ][ # # ]: 0 : Reference< XPropertySet> xCol = pColumn;
1842 [ # # ]: 0 : _rColumns->get().push_back(xCol);
1843 : : }
1844 : : else
1845 : 0 : bError = sal_True;
1846 : : }
1847 : : }
1848 : : else
1849 : 0 : bError = sal_True;
1850 : :
1851 : : // Table does not exist or lacking field
1852 [ # # ]: 0 : if (bError)
1853 : : {
1854 [ # # ]: 0 : ::rtl::OUString aNewColName(getUniqueColumnName(rColumnAlias));
1855 : :
1856 : : OParseColumn* pColumn = new OParseColumn(aNewColName,::rtl::OUString(),::rtl::OUString(),::rtl::OUString(),
1857 [ # # ][ # # ]: 0 : ColumnValue::NULLABLE_UNKNOWN,0,0,DataType::VARCHAR,sal_False,sal_False,isCaseSensitive());
1858 : 0 : pColumn->setFunction(sal_True);
1859 : 0 : pColumn->setAggregateFunction(bAggFkt);
1860 : :
1861 [ # # ][ # # ]: 0 : Reference< XPropertySet> xCol = pColumn;
1862 [ # # ]: 0 : _rColumns->get().push_back(xCol);
1863 : : }
1864 : : }
1865 : 528 : }
1866 : : //-----------------------------------------------------------------------------
1867 : 3448 : ::rtl::OUString OSQLParseTreeIterator::getUniqueColumnName(const ::rtl::OUString & rColumnName) const
1868 : : {
1869 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getUniqueColumnName" );
1870 : 3448 : ::rtl::OUString aAlias(rColumnName);
1871 : :
1872 : : OSQLColumns::Vector::const_iterator aIter = find(
1873 : 3448 : m_aSelectColumns->get().begin(),
1874 : 3448 : m_aSelectColumns->get().end(),
1875 : : aAlias,
1876 [ + - ]: 3448 : ::comphelper::UStringMixEqual( isCaseSensitive() )
1877 [ + - + - ]: 10344 : );
[ + - ]
1878 : 3448 : sal_Int32 i=1;
1879 [ + - ][ - + ]: 3448 : while(aIter != m_aSelectColumns->get().end())
1880 : : {
1881 : 0 : (aAlias = rColumnName) += ::rtl::OUString::valueOf(i++);
1882 : : aIter = find(
1883 : 0 : m_aSelectColumns->get().begin(),
1884 : 0 : m_aSelectColumns->get().end(),
1885 : : aAlias,
1886 [ # # ]: 0 : ::comphelper::UStringMixEqual( isCaseSensitive() )
1887 [ # # # # ]: 0 : );
[ # # ]
1888 : : }
1889 : 3448 : return aAlias;
1890 : : }
1891 : : //-----------------------------------------------------------------------------
1892 : 26 : void OSQLParseTreeIterator::setOrderByColumnName(const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange,sal_Bool bAscending)
1893 : : {
1894 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setOrderByColumnName" );
1895 [ + - ]: 26 : Reference<XPropertySet> xColumn = findColumn( rColumnName, rTableRange, false );
1896 [ + - ]: 26 : if ( xColumn.is() )
1897 [ + - ][ + - ]: 26 : m_aOrderColumns->get().push_back(new OOrderColumn( xColumn, rTableRange, isCaseSensitive(), bAscending ) );
[ + - ][ + - ]
[ + - ]
1898 : : else
1899 : : {
1900 : 0 : sal_Int32 nId = rColumnName.toInt32();
1901 [ # # ][ # # ]: 0 : if ( nId > 0 && nId < static_cast<sal_Int32>(m_aSelectColumns->get().size()) )
[ # # ]
1902 [ # # ][ # # ]: 0 : m_aOrderColumns->get().push_back( new OOrderColumn( ( m_aSelectColumns->get() )[nId-1], isCaseSensitive(), bAscending ) );
[ # # ][ # # ]
[ # # ]
1903 : 26 : }
1904 : :
1905 : : #ifdef SQL_TEST_PARSETREEITERATOR
1906 : : cout << "OSQLParseTreeIterator::setOrderByColumnName: "
1907 : : << (const char *) rColumnName << ", "
1908 : : << (const char *) rTableRange << ", "
1909 : : << (bAscending ? "true" : "false")
1910 : : << "\n";
1911 : : #endif
1912 : 26 : }
1913 : : //-----------------------------------------------------------------------------
1914 : 60 : void OSQLParseTreeIterator::setGroupByColumnName(const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange)
1915 : : {
1916 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setGroupByColumnName" );
1917 [ + - ]: 60 : Reference<XPropertySet> xColumn = findColumn( rColumnName, rTableRange, false );
1918 [ + - ]: 60 : if ( xColumn.is() )
1919 [ + - ][ + - ]: 60 : m_aGroupColumns->get().push_back(new OParseColumn(xColumn,isCaseSensitive()));
[ + - ][ + - ]
[ + - ]
1920 : : else
1921 : : {
1922 : 0 : sal_Int32 nId = rColumnName.toInt32();
1923 [ # # ][ # # ]: 0 : if ( nId > 0 && nId < static_cast<sal_Int32>(m_aSelectColumns->get().size()) )
[ # # ]
1924 [ # # ][ # # ]: 0 : m_aGroupColumns->get().push_back(new OParseColumn((m_aSelectColumns->get())[nId-1],isCaseSensitive()));
[ # # ][ # # ]
[ # # ]
1925 : 60 : }
1926 : :
1927 : : #ifdef SQL_TEST_PARSETREEITERATOR
1928 : : cout << "OSQLParseTreeIterator::setOrderByColumnName: "
1929 : : << (const char *) rColumnName << ", "
1930 : : << (const char *) rTableRange << ", "
1931 : : << (bAscending ? "true" : "false")
1932 : : << "\n";
1933 : : #endif
1934 : 60 : }
1935 : :
1936 : : //-----------------------------------------------------------------------------
1937 : 476 : const OSQLParseNode* OSQLParseTreeIterator::getWhereTree() const
1938 : : {
1939 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getWhereTree" );
1940 : :
1941 : :
1942 [ + + ]: 476 : if (!m_pParseTree)
1943 : 74 : return NULL;
1944 : :
1945 : : // Analyse parse tree (depending on statement type)
1946 : : // and set pointer to WHERE clause:
1947 : 402 : OSQLParseNode * pWhereClause = NULL;
1948 [ + - ]: 402 : if(getStatementType() == SQL_STATEMENT_SELECT)
1949 : : {
1950 : : OSL_ENSURE(m_pParseTree->count() >= 4,"ParseTreeIterator: error in parse tree!");
1951 : 402 : OSQLParseNode * pTableExp = m_pParseTree->getChild(3);
1952 : : OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!");
1953 : : OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: error in parse tree!");
1954 : : OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!");
1955 : :
1956 : 402 : pWhereClause = pTableExp->getChild(1);
1957 : : }
1958 [ # # ][ # # : 0 : else if (SQL_ISRULE(m_pParseTree,update_statement_searched) ||
# # # # ]
[ # # ]
1959 : 0 : SQL_ISRULE(m_pParseTree,delete_statement_searched))
1960 : : {
1961 : 0 : pWhereClause = m_pParseTree->getChild(m_pParseTree->count()-1);
1962 : : }
1963 [ + + ]: 402 : if(pWhereClause->count() != 2)
1964 : 246 : pWhereClause = NULL;
1965 : 476 : return pWhereClause;
1966 : : }
1967 : :
1968 : : //-----------------------------------------------------------------------------
1969 : 440 : const OSQLParseNode* OSQLParseTreeIterator::getOrderTree() const
1970 : : {
1971 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getOrderTree" );
1972 : :
1973 : :
1974 [ + + ][ - + ]: 440 : if (!m_pParseTree || getStatementType() != SQL_STATEMENT_SELECT)
[ + + ]
1975 : 74 : return NULL;
1976 : :
1977 : : // Analyse parse tree (depending on statement type)
1978 : : // and set pointer to ORDER clause:
1979 : 366 : OSQLParseNode * pOrderClause = NULL;
1980 : : OSL_ENSURE(m_pParseTree->count() >= 4,"ParseTreeIterator: error in parse tree!");
1981 : 366 : OSQLParseNode * pTableExp = m_pParseTree->getChild(3);
1982 : : OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!");
1983 : : OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: error in parse tree!");
1984 : : OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!");
1985 : :
1986 : 366 : pOrderClause = pTableExp->getChild(ORDER_BY_CHILD_POS);
1987 : : // If it is a order_by, it must not be empty
1988 [ + + ]: 366 : if(pOrderClause->count() != 3)
1989 : 348 : pOrderClause = NULL;
1990 : 440 : return pOrderClause;
1991 : : }
1992 : : //-----------------------------------------------------------------------------
1993 : 382 : const OSQLParseNode* OSQLParseTreeIterator::getGroupByTree() const
1994 : : {
1995 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getGroupByTree" );
1996 [ + + ][ - + ]: 382 : if (!m_pParseTree || getStatementType() != SQL_STATEMENT_SELECT)
[ + + ]
1997 : 74 : return NULL;
1998 : :
1999 : : // Analyse parse tree (depending on statement type)
2000 : : // and set pointer to ORDER clause:
2001 : 308 : OSQLParseNode * pGroupClause = NULL;
2002 : : OSL_ENSURE(m_pParseTree->count() >= 4,"ParseTreeIterator: error in parse tree!");
2003 : 308 : OSQLParseNode * pTableExp = m_pParseTree->getChild(3);
2004 : : OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!");
2005 : : OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: error in parse tree!");
2006 : : OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!");
2007 : :
2008 : 308 : pGroupClause = pTableExp->getChild(2);
2009 : : // If it is an order_by, it must not be empty
2010 [ + + ]: 308 : if(pGroupClause->count() != 3)
2011 : 250 : pGroupClause = NULL;
2012 : 382 : return pGroupClause;
2013 : : }
2014 : : //-----------------------------------------------------------------------------
2015 : 338 : const OSQLParseNode* OSQLParseTreeIterator::getHavingTree() const
2016 : : {
2017 [ + + ][ - + ]: 338 : if (!m_pParseTree || getStatementType() != SQL_STATEMENT_SELECT)
[ + + ]
2018 : 74 : return NULL;
2019 : :
2020 : : // Analyse parse tree (depending on statement type)
2021 : : // and set pointer to ORDER clause:
2022 : 264 : OSQLParseNode * pHavingClause = NULL;
2023 : : OSL_ENSURE(m_pParseTree->count() >= 4,"ParseTreeIterator: error in parse tree!");
2024 : 264 : OSQLParseNode * pTableExp = m_pParseTree->getChild(3);
2025 : : OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!");
2026 : : OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: error in parse tree!");
2027 : : OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!");
2028 : :
2029 : 264 : pHavingClause = pTableExp->getChild(3);
2030 : : // If it is an order_by, then it must not be empty
2031 [ + + ]: 264 : if(pHavingClause->count() < 1)
2032 : 210 : pHavingClause = NULL;
2033 : 338 : return pHavingClause;
2034 : : }
2035 : : // -----------------------------------------------------------------------------
2036 : 816 : sal_Bool OSQLParseTreeIterator::isTableNode(const OSQLParseNode* _pTableNode) const
2037 : : {
2038 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::isTableNode" );
2039 : 1632 : return _pTableNode && (SQL_ISRULE(_pTableNode,catalog_name) ||
2040 : 1632 : SQL_ISRULE(_pTableNode,schema_name) ||
2041 [ + - + - : 4080 : SQL_ISRULE(_pTableNode,table_name));
+ - + - +
- ][ + - ]
[ + + ]
2042 : : }
2043 : : // -----------------------------------------------------------------------------
2044 : 468 : const OSQLParseNode* OSQLParseTreeIterator::getSimpleWhereTree() const
2045 : : {
2046 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleWhereTree" );
2047 : 468 : const OSQLParseNode* pNode = getWhereTree();
2048 [ + + ]: 468 : return pNode ? pNode->getChild(1) : NULL;
2049 : : }
2050 : : // -----------------------------------------------------------------------------
2051 : 352 : const OSQLParseNode* OSQLParseTreeIterator::getSimpleOrderTree() const
2052 : : {
2053 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleOrderTree" );
2054 : 352 : const OSQLParseNode* pNode = getOrderTree();
2055 [ + + ]: 352 : return pNode ? pNode->getChild(2) : NULL;
2056 : : }
2057 : : // -----------------------------------------------------------------------------
2058 : 382 : const OSQLParseNode* OSQLParseTreeIterator::getSimpleGroupByTree() const
2059 : : {
2060 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleGroupByTree" );
2061 : 382 : const OSQLParseNode* pNode = getGroupByTree();
2062 [ + + ]: 382 : return pNode ? pNode->getChild(2) : NULL;
2063 : : }
2064 : : // -----------------------------------------------------------------------------
2065 : 338 : const OSQLParseNode* OSQLParseTreeIterator::getSimpleHavingTree() const
2066 : : {
2067 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleHavingTree" );
2068 : 338 : const OSQLParseNode* pNode = getHavingTree();
2069 [ + + ]: 338 : return pNode ? pNode->getChild(1) : NULL;
2070 : : }
2071 : :
2072 : : // -----------------------------------------------------------------------------
2073 : 124 : Reference< XPropertySet > OSQLParseTreeIterator::findColumn( const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange, bool _bLookInSubTables )
2074 : : {
2075 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::findColumn" );
2076 : 124 : Reference< XPropertySet > xColumn = findColumn( *m_pImpl->m_pTables, rColumnName, rTableRange );
2077 [ # # ][ - + ]: 124 : if ( !xColumn.is() && _bLookInSubTables )
[ - + ]
2078 [ # # ][ # # ]: 0 : xColumn = findColumn( *m_pImpl->m_pSubTables, rColumnName, rTableRange );
2079 : 124 : return xColumn;
2080 : : }
2081 : :
2082 : : // -----------------------------------------------------------------------------
2083 : 124 : Reference< XPropertySet > OSQLParseTreeIterator::findColumn(const OSQLTables& _rTables,const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange)
2084 : : {
2085 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::findColumn" );
2086 : 124 : Reference< XPropertySet > xColumn;
2087 [ + + ]: 124 : if ( !rTableRange.isEmpty() )
2088 : : {
2089 [ + - ]: 22 : ConstOSQLTablesIterator aFind = _rTables.find(rTableRange);
2090 : :
2091 [ + - + - : 110 : if ( aFind != _rTables.end()
+ - ][ + - ]
[ + - ]
[ + - # # ]
2092 : 22 : && aFind->second.is()
2093 [ + - ][ + - ]: 44 : && aFind->second->getColumns().is()
[ + - ][ # # ]
2094 [ + - ][ + - ]: 44 : && aFind->second->getColumns()->hasByName(rColumnName) )
[ + - ][ + - ]
[ + - ][ # # ]
2095 [ + - ][ + - ]: 22 : aFind->second->getColumns()->getByName(rColumnName) >>= xColumn;
[ + - ][ + - ]
[ + - ]
2096 : : }
2097 [ + + ]: 124 : if ( !xColumn.is() )
2098 : : {
2099 : 102 : OSQLTables::const_iterator aEnd = _rTables.end();
2100 [ + - ]: 204 : for(OSQLTables::const_iterator aIter = _rTables.begin(); aIter != aEnd; ++aIter)
2101 : : {
2102 [ + - ]: 102 : if ( aIter->second.is() )
2103 : : {
2104 [ + - ][ + - ]: 102 : Reference<XNameAccess> xColumns = aIter->second->getColumns();
2105 [ + - ][ + - ]: 102 : if( xColumns.is() && xColumns->hasByName(rColumnName) && (xColumns->getByName(rColumnName) >>= xColumn) )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ # # ]
2106 : : {
2107 : : OSL_ENSURE(xColumn.is(),"Column isn't a propertyset!");
2108 : : break; // This column must only exits once
2109 [ - + ]: 102 : }
2110 : : }
2111 : : }
2112 : : }
2113 : 124 : return xColumn;
2114 : : }
2115 : :
2116 : : // -----------------------------------------------------------------------------
2117 : 88 : void OSQLParseTreeIterator::impl_appendError( IParseContext::ErrorCode _eError, const ::rtl::OUString* _pReplaceToken1, const ::rtl::OUString* _pReplaceToken2 )
2118 : : {
2119 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_appendError" );
2120 [ + - ]: 88 : ::rtl::OUString sErrorMessage = m_rParser.getContext().getErrorMessage( _eError );
2121 [ + - ]: 88 : if ( _pReplaceToken1 )
2122 : : {
2123 : 88 : bool bTwoTokens = ( _pReplaceToken2 != NULL );
2124 [ - + ]: 88 : const sal_Char* pPlaceHolder1 = bTwoTokens ? "#1" : "#";
2125 : 88 : const ::rtl::OUString sPlaceHolder1 = ::rtl::OUString::createFromAscii( pPlaceHolder1 );
2126 : :
2127 : 88 : sErrorMessage = sErrorMessage.replaceAt( sErrorMessage.indexOf( sPlaceHolder1 ), sPlaceHolder1.getLength(), *_pReplaceToken1 );
2128 [ - + ]: 88 : if ( _pReplaceToken2 )
2129 : 88 : sErrorMessage = sErrorMessage.replaceAt( sErrorMessage.indexOf( "#2" ), 2, *_pReplaceToken2 );
2130 : : }
2131 : :
2132 : : impl_appendError( SQLException(
2133 [ + - ][ + - ]: 88 : sErrorMessage, NULL, getStandardSQLState( SQL_GENERAL_ERROR ), 1000, Any() ) );
[ + - ][ + - ]
[ + - ]
2134 : 88 : }
2135 : :
2136 : : // -----------------------------------------------------------------------------
2137 : 88 : void OSQLParseTreeIterator::impl_appendError( const SQLException& _rError )
2138 : : {
2139 : : RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_appendError" );
2140 [ - + ]: 88 : if ( !m_aErrors.Message.isEmpty() )
2141 : : {
2142 : 0 : SQLException* pErrorChain = &m_aErrors;
2143 [ # # ]: 0 : while ( pErrorChain->NextException.hasValue() )
2144 : 0 : pErrorChain = static_cast< SQLException* >( pErrorChain->NextException.pData );
2145 : 0 : pErrorChain->NextException <<= _rError;
2146 : : }
2147 : : else
2148 : 88 : m_aErrors = _rError;
2149 : 88 : }
2150 : : // -----------------------------------------------------------------------------
2151 : 0 : sal_Int32 OSQLParseTreeIterator::getFunctionReturnType(const OSQLParseNode* _pNode )
2152 : : {
2153 : 0 : sal_Int32 nType = DataType::OTHER;
2154 : 0 : ::rtl::OUString sFunctionName;
2155 [ # # ][ # # ]: 0 : if ( SQL_ISRULE(_pNode,length_exp) )
[ # # ][ # # ]
2156 : : {
2157 [ # # ][ # # ]: 0 : _pNode->getChild(0)->getChild(0)->parseNodeToStr(sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
[ # # ]
2158 [ # # ]: 0 : nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() );
2159 : : }
2160 [ # # ][ # # ]: 0 : else if ( SQL_ISRULE(_pNode,num_value_exp) || SQL_ISRULE(_pNode,term) || SQL_ISRULE(_pNode,factor) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2161 : : {
2162 : 0 : nType = DataType::DOUBLE;
2163 : : }
2164 : : else
2165 : : {
2166 [ # # ][ # # ]: 0 : _pNode->getChild(0)->parseNodeToStr(sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False );
2167 : :
2168 : : // MIN and MAX have another return type, we have to check the expression itself.
2169 : : // @see http://qa.openoffice.org/issues/show_bug.cgi?id=99566
2170 [ # # ][ # # ]: 0 : if ( SQL_ISRULE(_pNode,general_set_fct) && (SQL_ISTOKEN(_pNode->getChild(0),MIN) || SQL_ISTOKEN(_pNode->getChild(0),MAX) ))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2171 : : {
2172 [ # # ]: 0 : const OSQLParseNode* pValueExp = _pNode->getChild(3);
2173 [ # # ][ # # ]: 0 : if (SQL_ISRULE(pValueExp,column_ref))
[ # # ][ # # ]
2174 : : {
2175 : 0 : ::rtl::OUString sColumnName;
2176 : 0 : ::rtl::OUString aTableRange;
2177 [ # # ]: 0 : getColumnRange(pValueExp,sColumnName,aTableRange);
2178 : : OSL_ENSURE(!sColumnName.isEmpty(),"Columnname must not be empty!");
2179 [ # # ]: 0 : Reference<XPropertySet> xColumn = findColumn( sColumnName, aTableRange, true );
2180 : :
2181 [ # # ]: 0 : if ( xColumn.is() )
2182 : : {
2183 [ # # ][ # # ]: 0 : xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_TYPE)) >>= nType;
[ # # ][ # # ]
2184 : 0 : }
2185 : : }
2186 : : else
2187 : : {
2188 [ # # ][ # # ]: 0 : if ( SQL_ISRULE(pValueExp,num_value_exp) || SQL_ISRULE(pValueExp,term) || SQL_ISRULE(pValueExp,factor) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
2189 : : {
2190 : 0 : nType = DataType::DOUBLE;
2191 : : }
2192 [ # # ][ # # ]: 0 : else if ( SQL_ISRULE(pValueExp,datetime_primary) )
[ # # ][ # # ]
2193 : : {
2194 [ # # ]: 0 : switch(pValueExp->getChild(0)->getTokenID() )
[ # # # # ]
2195 : : {
2196 : : case SQL_TOKEN_CURRENT_DATE:
2197 : 0 : nType = DataType::DATE;
2198 : 0 : break;
2199 : : case SQL_TOKEN_CURRENT_TIME:
2200 : 0 : nType = DataType::TIME;
2201 : 0 : break;
2202 : : case SQL_TOKEN_CURRENT_TIMESTAMP:
2203 : 0 : nType = DataType::TIMESTAMP;
2204 : 0 : break;
2205 : : }
2206 : : }
2207 [ # # ][ # # ]: 0 : else if ( SQL_ISRULE(pValueExp,value_exp_primary) )
[ # # ][ # # ]
2208 : : {
2209 [ # # ][ # # ]: 0 : nType = getFunctionReturnType(pValueExp->getChild(1));
2210 : : }
2211 [ # # ][ # # ]: 0 : else if ( SQL_ISRULE(pValueExp,concatenation)
[ # # # # ]
[ # # # # ]
[ # # # # ]
[ # # # # ]
[ # # # # ]
[ # # # #
# # ][ # # ]
2212 [ # # ]: 0 : || SQL_ISRULE(pValueExp,char_factor)
2213 [ # # ]: 0 : || SQL_ISRULE(pValueExp,bit_value_fct)
2214 [ # # ]: 0 : || SQL_ISRULE(pValueExp,char_value_fct)
2215 [ # # ]: 0 : || SQL_ISRULE(pValueExp,char_substring_fct)
2216 [ # # ]: 0 : || SQL_ISRULE(pValueExp,fold)
2217 : 0 : || SQL_ISTOKEN(pValueExp,STRING) )
2218 : : {
2219 : 0 : nType = DataType::VARCHAR;
2220 : : }
2221 : : }
2222 [ # # ]: 0 : if ( nType == DataType::OTHER )
2223 : 0 : nType = DataType::DOUBLE;
2224 : : }
2225 : : else
2226 [ # # ]: 0 : nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() );
2227 : : }
2228 : :
2229 : 0 : return nType;
2230 : : }
2231 : :
2232 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|