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