1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sqliterator.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include "connectivity/sqliterator.hxx"
34 #include "connectivity/sdbcx/VTable.hxx"
35 #include <connectivity/sqlparse.hxx>
36 #include <connectivity/dbtools.hxx>
37 #include <connectivity/sqlerror.hxx>
38 #include <com/sun/star/sdbc/ColumnValue.hpp>
39 #include <com/sun/star/sdbc/DataType.hpp>
40 #include <com/sun/star/sdbc/XRow.hpp>
41 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
42 #include <com/sun/star/sdb/ErrorCondition.hpp>
43 #ifdef SQL_TEST_PARSETREEITERATOR
46 #include "connectivity/PColumn.hxx"
47 #include "connectivity/dbtools.hxx"
48 #include <tools/diagnose_ex.h>
49 #include "TConnection.hxx"
50 #include <comphelper/types.hxx>
51 #include <connectivity/dbmetadata.hxx>
52 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
53 #include "diagnose_ex.h"
54 #include <rtl/logfile.hxx>
56 using namespace ::comphelper
;
57 using namespace ::connectivity
;
58 using namespace ::connectivity::sdbcx
;
59 using namespace ::dbtools
;
60 using namespace ::connectivity::parse
;
61 using namespace ::com::sun::star
;
62 using namespace ::com::sun::star::uno
;
63 using namespace ::com::sun::star::container
;
64 using namespace ::com::sun::star::sdbcx
;
65 using namespace ::com::sun::star::beans
;
66 using namespace ::com::sun::star::sdbc
;
67 using namespace ::com::sun::star::sdb
;
69 namespace connectivity
71 struct OSQLParseTreeIteratorImpl
73 Reference
< XConnection
> m_xConnection
;
74 Reference
< XDatabaseMetaData
> m_xDatabaseMetaData
;
75 Reference
< XNameAccess
> m_xTableContainer
;
76 Reference
< XNameAccess
> m_xQueryContainer
;
78 ::boost::shared_ptr
< OSQLTables
> m_pTables
; /// all tables which participate in the SQL statement
79 ::boost::shared_ptr
< OSQLTables
> m_pSubTables
; /// all tables from sub queries not the tables from the select tables
80 ::boost::shared_ptr
< QueryNameSet
> m_pForbiddenQueryNames
;
82 sal_uInt32 m_nIncludeMask
;
84 bool m_bIsCaseSensitive
;
86 OSQLParseTreeIteratorImpl( const Reference
< XConnection
>& _rxConnection
, const Reference
< XNameAccess
>& _rxTables
)
87 :m_xConnection( _rxConnection
)
88 ,m_nIncludeMask( OSQLParseTreeIterator::All
)
89 ,m_bIsCaseSensitive( true )
91 OSL_PRECOND( m_xConnection
.is(), "OSQLParseTreeIteratorImpl::OSQLParseTreeIteratorImpl: invalid connection!" );
92 m_xDatabaseMetaData
= m_xConnection
->getMetaData();
94 m_bIsCaseSensitive
= m_xDatabaseMetaData
.is() && m_xDatabaseMetaData
->storesMixedCaseQuotedIdentifiers();
95 m_pTables
.reset( new OSQLTables( m_bIsCaseSensitive
) );
96 m_pSubTables
.reset( new OSQLTables( m_bIsCaseSensitive
) );
98 m_xTableContainer
= _rxTables
;
100 DatabaseMetaData
aMetaData( m_xConnection
);
101 if ( aMetaData
.supportsSubqueriesInFrom() )
103 // connections might support the XQueriesSupplier interface, if they implement the css.sdb.Connection
105 Reference
< XQueriesSupplier
> xSuppQueries( m_xConnection
, UNO_QUERY
);
106 if ( xSuppQueries
.is() )
107 m_xQueryContainer
= xSuppQueries
->getQueries();
112 inline bool isQueryAllowed( const ::rtl::OUString
& _rQueryName
)
114 if ( !m_pForbiddenQueryNames
.get() )
116 if ( m_pForbiddenQueryNames
->find( _rQueryName
) == m_pForbiddenQueryNames
->end() )
122 //-------------------------------------------------------------------------
123 /** helper class for temporarily adding a query name to a list of forbidden query names
125 class ForbidQueryName
127 ::boost::shared_ptr
< QueryNameSet
>& m_rpAllForbiddenNames
;
128 ::rtl::OUString m_sForbiddenQueryName
;
131 ForbidQueryName( OSQLParseTreeIteratorImpl
& _rIteratorImpl
, const ::rtl::OUString _rForbiddenQueryName
)
132 :m_rpAllForbiddenNames( _rIteratorImpl
.m_pForbiddenQueryNames
)
133 ,m_sForbiddenQueryName( _rForbiddenQueryName
)
135 if ( !m_rpAllForbiddenNames
.get() )
136 m_rpAllForbiddenNames
.reset( new QueryNameSet
);
137 m_rpAllForbiddenNames
->insert( m_sForbiddenQueryName
);
142 m_rpAllForbiddenNames
->erase( m_sForbiddenQueryName
);
146 //-----------------------------------------------------------------------------
147 OSQLParseTreeIterator::OSQLParseTreeIterator(const Reference
< XConnection
>& _rxConnection
,
148 const Reference
< XNameAccess
>& _rxTables
,
149 const OSQLParser
& _rParser
,
150 const OSQLParseNode
* pRoot
)
151 :m_rParser( _rParser
)
152 ,m_pImpl( new OSQLParseTreeIteratorImpl( _rxConnection
, _rxTables
) )
154 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::OSQLParseTreeIterator" );
158 //-----------------------------------------------------------------------------
159 OSQLParseTreeIterator::OSQLParseTreeIterator( const OSQLParseTreeIterator
& _rParentIterator
, const OSQLParser
& _rParser
, const OSQLParseNode
* pRoot
)
160 :m_rParser( _rParser
)
161 ,m_pImpl( new OSQLParseTreeIteratorImpl( _rParentIterator
.m_pImpl
->m_xConnection
, _rParentIterator
.m_pImpl
->m_xTableContainer
) )
163 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::OSQLParseTreeIterator" );
164 m_pImpl
->m_pForbiddenQueryNames
= _rParentIterator
.m_pImpl
->m_pForbiddenQueryNames
;
165 setParseTree( pRoot
);
168 //-----------------------------------------------------------------------------
169 OSQLParseTreeIterator::~OSQLParseTreeIterator()
174 // -----------------------------------------------------------------------------
175 const OSQLTables
& OSQLParseTreeIterator::getTables() const
177 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getTables" );
178 return *m_pImpl
->m_pTables
;
181 // -----------------------------------------------------------------------------
182 bool OSQLParseTreeIterator::isCaseSensitive() const
184 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::isCaseSensitive" );
185 return m_pImpl
->m_bIsCaseSensitive
;
188 // -----------------------------------------------------------------------------
189 void OSQLParseTreeIterator::dispose()
191 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::dispose" );
192 m_aSelectColumns
= NULL
;
193 m_aGroupColumns
= NULL
;
194 m_aOrderColumns
= NULL
;
195 m_aParameters
= NULL
;
196 m_pImpl
->m_xTableContainer
= NULL
;
197 m_pImpl
->m_xDatabaseMetaData
= NULL
;
198 m_aCreateColumns
= NULL
;
199 m_pImpl
->m_pTables
->clear();
200 m_pImpl
->m_pSubTables
->clear();
202 //-----------------------------------------------------------------------------
203 void OSQLParseTreeIterator::setParseTree(const OSQLParseNode
* pNewParseTree
)
205 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setParseTree" );
206 m_pImpl
->m_pTables
->clear();
207 m_pImpl
->m_pSubTables
->clear();
209 m_aSelectColumns
= new OSQLColumns();
210 m_aGroupColumns
= new OSQLColumns();
211 m_aOrderColumns
= new OSQLColumns();
212 m_aParameters
= new OSQLColumns();
213 m_aCreateColumns
= new OSQLColumns();
215 m_pParseTree
= pNewParseTree
;
218 m_eStatementType
= SQL_STATEMENT_UNKNOWN
;
222 // falls m_pParseTree aber keine Connection, dann Fehler
223 if ( !m_pImpl
->m_xTableContainer
.is() )
226 m_aErrors
= SQLException();
229 // Statement-Typ ermitteln ...
230 if (SQL_ISRULE(m_pParseTree
,select_statement
) || SQL_ISRULE(m_pParseTree
,union_statement
) )
232 m_eStatementType
= SQL_STATEMENT_SELECT
;
234 else if (SQL_ISRULE(m_pParseTree
,insert_statement
))
236 m_eStatementType
= SQL_STATEMENT_INSERT
;
238 else if (SQL_ISRULE(m_pParseTree
,update_statement_searched
))
240 m_eStatementType
= SQL_STATEMENT_UPDATE
;
242 else if (SQL_ISRULE(m_pParseTree
,delete_statement_searched
))
244 m_eStatementType
= SQL_STATEMENT_DELETE
;
246 else if (m_pParseTree
->count() == 3 && SQL_ISRULE(m_pParseTree
->getChild(1),odbc_call_spec
))
248 m_eStatementType
= SQL_STATEMENT_ODBC_CALL
;
250 else if (SQL_ISRULE(m_pParseTree
->getChild(0),base_table_def
))
252 m_eStatementType
= SQL_STATEMENT_CREATE_TABLE
;
253 m_pParseTree
= m_pParseTree
->getChild(0);
257 m_eStatementType
= SQL_STATEMENT_UNKNOWN
;
258 //aIteratorStatus.setInvalidStatement();
263 //-----------------------------------------------------------------------------
266 //.........................................................................
267 static void impl_getRowString( const Reference
< XRow
>& _rxRow
, const sal_Int32 _nColumnIndex
, ::rtl::OUString
& _out_rString
)
269 _out_rString
= _rxRow
->getString( _nColumnIndex
);
270 if ( _rxRow
->wasNull() )
271 _out_rString
= ::rtl::OUString();
274 //.........................................................................
275 static ::rtl::OUString
lcl_findTableInMetaData(
276 const Reference
< XDatabaseMetaData
>& _rxDBMeta
, const ::rtl::OUString
& _rCatalog
,
277 const ::rtl::OUString
& _rSchema
, const ::rtl::OUString
& _rTableName
)
279 ::rtl::OUString sComposedName
;
281 static const ::rtl::OUString
s_sTableTypeView(RTL_CONSTASCII_USTRINGPARAM("VIEW"));
282 static const ::rtl::OUString
s_sTableTypeTable(RTL_CONSTASCII_USTRINGPARAM("TABLE"));
283 static const ::rtl::OUString s_sWildcard
= ::rtl::OUString::createFromAscii("%");
285 // we want all catalogues, all schemas, all tables
286 Sequence
< ::rtl::OUString
> sTableTypes(3);
287 sTableTypes
[0] = s_sTableTypeView
;
288 sTableTypes
[1] = s_sTableTypeTable
;
289 sTableTypes
[2] = s_sWildcard
; // just to be sure to include anything else ....
291 if ( _rxDBMeta
.is() )
293 sComposedName
= ::rtl::OUString();
295 Reference
< XResultSet
> xRes
= _rxDBMeta
->getTables(
296 _rCatalog
.getLength() ? makeAny( _rCatalog
) : Any(), _rSchema
.getLength() ? _rSchema
: s_sWildcard
, _rTableName
, sTableTypes
);
298 Reference
< XRow
> xCurrentRow( xRes
, UNO_QUERY
);
299 if ( xCurrentRow
.is() && xRes
->next() )
301 ::rtl::OUString sCatalog
, sSchema
, sName
;
303 impl_getRowString( xCurrentRow
, 1, sCatalog
);
304 impl_getRowString( xCurrentRow
, 2, sSchema
);
305 impl_getRowString( xCurrentRow
, 3, sName
);
307 sComposedName
= ::dbtools::composeTableName(
313 ::dbtools::eInDataManipulation
317 return sComposedName
;
321 //-----------------------------------------------------------------------------
322 void OSQLParseTreeIterator::impl_getQueryParameterColumns( const OSQLTable
& _rQuery
)
324 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_getQueryParameterColumns" );
325 if ( ( m_pImpl
->m_nIncludeMask
& Parameters
) != Parameters
)
326 // parameters not to be included in the traversal
329 ::vos::ORef
< OSQLColumns
> pSubQueryParameterColumns( new OSQLColumns() );
331 // get the command and the EscapeProcessing properties from the sub query
332 ::rtl::OUString sSubQueryCommand
;
333 sal_Bool bEscapeProcessing
= sal_False
;
336 Reference
< XPropertySet
> xQueryProperties( _rQuery
, UNO_QUERY_THROW
);
337 OSL_VERIFY( xQueryProperties
->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_COMMAND
) ) >>= sSubQueryCommand
);
338 OSL_VERIFY( xQueryProperties
->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING
) ) >>= bEscapeProcessing
);
340 catch( const Exception
& )
342 DBG_UNHANDLED_EXCEPTION();
345 // parse the sub query
348 if ( !bEscapeProcessing
|| ( sSubQueryCommand
.getLength() == 0 ) )
351 ::rtl::OUString sError
;
352 ::std::auto_ptr
< OSQLParseNode
> pSubQueryNode( const_cast< OSQLParser
& >( m_rParser
).parseTree( sError
, sSubQueryCommand
, sal_False
) );
353 if ( !pSubQueryNode
.get() )
356 OSQLParseTreeIterator
aSubQueryIterator( *this, m_rParser
, pSubQueryNode
.get() );
357 aSubQueryIterator
.traverseSome( Parameters
| SelectColumns
);
358 // SelectColumns might also contain parameters
359 // #i77635# - 2007-07-23 / frank.schoenheit@sun.com
360 pSubQueryParameterColumns
= aSubQueryIterator
.getParameters();
361 aSubQueryIterator
.dispose();
365 // copy the parameters of the sub query to our own parameter array
366 ::std::copy( pSubQueryParameterColumns
->get().begin(), pSubQueryParameterColumns
->get().end(),
367 ::std::insert_iterator
< OSQLColumns::Vector
>( m_aParameters
->get(), m_aParameters
->get().end() ) );
370 //-----------------------------------------------------------------------------
371 OSQLTable
OSQLParseTreeIterator::impl_locateRecordSource( const ::rtl::OUString
& _rComposedName
)
373 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_locateRecordSource" );
374 if ( !_rComposedName
.getLength() )
376 OSL_ENSURE( false, "OSQLParseTreeIterator::impl_locateRecordSource: no object name at all?" );
381 ::rtl::OUString
sComposedName( _rComposedName
);
385 ::rtl::OUString sCatalog
, sSchema
, sName
;
386 qualifiedNameComponents( m_pImpl
->m_xDatabaseMetaData
, sComposedName
, sCatalog
, sSchema
, sName
, ::dbtools::eInDataManipulation
);
388 // check whether there is a query with the given name
389 bool bQueryDoesExist
= m_pImpl
->m_xQueryContainer
.is() && m_pImpl
->m_xQueryContainer
->hasByName( sComposedName
);
391 // check whether the table container contains an object with the given name
392 if ( !bQueryDoesExist
&& !m_pImpl
->m_xTableContainer
->hasByName( sComposedName
) )
393 sComposedName
= lcl_findTableInMetaData( m_pImpl
->m_xDatabaseMetaData
, sCatalog
, sSchema
, sName
);
394 bool bTableDoesExist
= m_pImpl
->m_xTableContainer
->hasByName( sComposedName
);
396 // now obtain the object
398 // if we're creating a table, and there already is a table or query with the same name,
399 // this is worth an error
400 if ( SQL_STATEMENT_CREATE_TABLE
== m_eStatementType
)
402 if ( bQueryDoesExist
)
403 impl_appendError( IParseContext::ERROR_INVALID_QUERY_EXIST
, &sName
);
404 else if ( bTableDoesExist
)
405 impl_appendError( IParseContext::ERROR_INVALID_TABLE_EXIST
, &sName
);
407 aReturn
= impl_createTableObject( sName
, sCatalog
, sSchema
);
411 // queries win over tables, so if there's a query with this name, take this, no matter if
412 // there's a table, too
413 if ( bQueryDoesExist
)
415 if ( !m_pImpl
->isQueryAllowed( sComposedName
) )
417 impl_appendError( m_rParser
.getErrorHelper().getSQLException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES
, NULL
) );
421 m_pImpl
->m_xQueryContainer
->getByName( sComposedName
) >>= aReturn
;
423 // collect the parameters from the sub query
424 ForbidQueryName
aForbidName( *m_pImpl
, sComposedName
);
425 impl_getQueryParameterColumns( aReturn
);
427 else if ( bTableDoesExist
)
428 m_pImpl
->m_xTableContainer
->getByName( sComposedName
) >>= aReturn
;
431 if ( m_pImpl
->m_xQueryContainer
.is() )
432 // the connection on which we're working supports sub queries in from (else
433 // m_xQueryContainer would not have been set), so emit a better error message
434 impl_appendError( IParseContext::ERROR_INVALID_TABLE_OR_QUERY
, &sName
);
436 impl_appendError( IParseContext::ERROR_INVALID_TABLE
, &sName
);
442 impl_appendError( IParseContext::ERROR_INVALID_TABLE
, &sComposedName
);
448 //-----------------------------------------------------------------------------
449 void OSQLParseTreeIterator::traverseOneTableName( OSQLTables
& _rTables
,const OSQLParseNode
* pTableName
, const ::rtl::OUString
& rTableRange
)
451 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseOneTableName" );
452 if ( ( m_pImpl
->m_nIncludeMask
& TableNames
) != TableNames
)
453 // tables should not be included in the traversal
456 OSL_ENSURE(pTableName
!= NULL
,"OSQLParseTreeIterator::traverseOneTableName: pTableName == NULL");
459 ::rtl::OUString aSchema
,aTableName
,aComposedName
;
460 ::rtl::OUString
aTableRange(rTableRange
);
462 // Tabellenname abholen
463 OSQLParseNode::getTableComponents(pTableName
,aCatalog
,aSchema
,aTableName
,m_pImpl
->m_xDatabaseMetaData
);
465 // create the composed name like DOMAIN.USER.TABLE1
466 aComposedName
= ::dbtools::composeTableName(m_pImpl
->m_xDatabaseMetaData
,
467 aCatalog
.hasValue() ? ::comphelper::getString(aCatalog
) : ::rtl::OUString(),
471 ::dbtools::eInDataManipulation
);
473 // if there is no alias for the table name assign the orignal name to it
474 if ( !aTableRange
.getLength() )
475 aTableRange
= aComposedName
;
477 // get the object representing this table/query
478 OSQLTable aTable
= impl_locateRecordSource( aComposedName
);
480 _rTables
[ aTableRange
] = aTable
;
483 //-----------------------------------------------------------------------------
484 void OSQLParseTreeIterator::getQualified_join( OSQLTables
& _rTables
, const OSQLParseNode
*pTableRef
, ::rtl::OUString
& aTableRange
)
486 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getQualified_join" );
487 OSL_PRECOND( SQL_ISRULE( pTableRef
, cross_union
) || SQL_ISRULE( pTableRef
, qualified_join
) ,
488 "OSQLParseTreeIterator::getQualified_join: illegal node!" );
490 aTableRange
= ::rtl::OUString();
492 const OSQLParseNode
* pNode
= getTableNode(_rTables
,pTableRef
->getChild(0),aTableRange
);
493 if ( isTableNode( pNode
) )
494 traverseOneTableName( _rTables
, pNode
, aTableRange
);
497 if(SQL_ISRULE(pTableRef
,cross_union
) || pTableRef
->getChild(1)->getTokenID() != SQL_TOKEN_NATURAL
)
500 pNode
= getTableNode(_rTables
,pTableRef
->getChild(nPos
),aTableRange
);
501 if ( isTableNode( pNode
) )
502 traverseOneTableName( _rTables
, pNode
, aTableRange
);
504 //-----------------------------------------------------------------------------
505 const OSQLParseNode
* OSQLParseTreeIterator::getTableNode( OSQLTables
& _rTables
, const OSQLParseNode
*pTableRef
,::rtl::OUString
& rTableRange
)
507 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getTableNode" );
508 OSL_PRECOND( SQL_ISRULE( pTableRef
, table_ref
) || SQL_ISRULE( pTableRef
, joined_table
)
509 || SQL_ISRULE( pTableRef
, qualified_join
) || SQL_ISRULE( pTableRef
, cross_union
),
510 "OSQLParseTreeIterator::getTableNode: only to be called for table_ref nodes!" );
512 const OSQLParseNode
* pTableNameNode
= NULL
;
514 if ( SQL_ISRULE( pTableRef
, joined_table
) )
516 getQualified_join( _rTables
, pTableRef
->getChild(1), rTableRange
);
518 if ( SQL_ISRULE( pTableRef
, qualified_join
) || SQL_ISRULE( pTableRef
, cross_union
) )
520 getQualified_join( _rTables
, pTableRef
, rTableRange
);
524 rTableRange
= OSQLParseNode::getTableRange(pTableRef
);
525 if ( ( pTableRef
->count() == 4 ) // '{' SQL_TOKEN_OJ joined_table '}'
526 || ( pTableRef
->count() == 5 ) // '(' joined_table ')' range_variable op_column_commalist
529 getQualified_join( _rTables
, pTableRef
->getChild(6 - pTableRef
->count()), rTableRange
);
531 else if ( pTableRef
->count() == 3 ) // subquery range_variable op_column_commalist || '(' joined_table ')'
533 const OSQLParseNode
* pSubQuery
= pTableRef
->getChild(0);
534 if ( pSubQuery
->isToken() )
536 getQualified_join( _rTables
, pTableRef
->getChild(1), rTableRange
);
540 OSL_ENSURE( pSubQuery
->count() == 3, "sub queries should have 3 children!" );
541 const OSQLParseNode
* pQueryExpression
= pSubQuery
->getChild(1);
542 if ( SQL_ISRULE( pQueryExpression
, select_statement
) )
544 getSelect_statement( *m_pImpl
->m_pSubTables
, pQueryExpression
);
548 OSL_ENSURE( false, "OSQLParseTreeIterator::getTableNode: subquery which is no select_statement: not yet implemented!" );
552 else if ( pTableRef
->count() == 2 ) // table_node table_primary_as_range_column
554 pTableNameNode
= pTableRef
->getChild(0);
557 OSL_ENSURE( false, "OSQLParseTreeIterator::getTableNode: unhandled case!" );
560 return pTableNameNode
;
562 //-----------------------------------------------------------------------------
563 void OSQLParseTreeIterator::getSelect_statement(OSQLTables
& _rTables
,const OSQLParseNode
* pSelect
)
565 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSelect_statement" );
566 if(SQL_ISRULE(pSelect
,union_statement
))
568 getSelect_statement(_rTables
,pSelect
->getChild(0));
569 //getSelect_statement(pSelect->getChild(3));
572 OSQLParseNode
* pTableRefCommalist
= pSelect
->getChild(3)->getChild(0)->getChild(1);
574 OSL_ENSURE(pTableRefCommalist
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
575 OSL_ENSURE(SQL_ISRULE(pTableRefCommalist
,table_ref_commalist
),"OSQLParseTreeIterator: error in parse tree!");
577 const OSQLParseNode
* pTableName
= NULL
;
578 ::rtl::OUString aTableRange
;
579 for (sal_uInt32 i
= 0; i
< pTableRefCommalist
->count(); i
++)
580 { // from clause durchlaufen
581 aTableRange
= ::rtl::OUString();
583 const OSQLParseNode
* pTableListElement
= pTableRefCommalist
->getChild(i
);
584 if ( isTableNode( pTableListElement
) )
586 traverseOneTableName( _rTables
, pTableListElement
, aTableRange
);
588 else if ( SQL_ISRULE( pTableListElement
, table_ref
) )
590 // Tabellenreferenz kann aus Tabellennamen, Tabellennamen (+),'('joined_table')'(+) bestehen
591 pTableName
= pTableListElement
->getChild(0);
592 if( isTableNode( pTableName
) )
593 { // Tabellennamen gefunden
594 aTableRange
= OSQLParseNode::getTableRange(pTableListElement
);
595 traverseOneTableName( _rTables
, pTableName
, aTableRange
);
597 else if(SQL_ISPUNCTUATION(pTableName
,"{"))
598 { // '{' SQL_TOKEN_OJ joined_table '}'
599 getQualified_join( _rTables
, pTableListElement
->getChild(2), aTableRange
);
602 { // '(' joined_table ')' range_variable op_column_commalist
603 getTableNode( _rTables
, pTableListElement
, aTableRange
);
606 else if (SQL_ISRULE( pTableListElement
, qualified_join
) || SQL_ISRULE( pTableListElement
, cross_union
) )
608 getQualified_join( _rTables
, pTableListElement
, aTableRange
);
610 else if ( SQL_ISRULE( pTableListElement
, joined_table
) )
612 getQualified_join( _rTables
, pTableListElement
->getChild(1), aTableRange
);
615 // if (! aIteratorStatus.IsSuccessful()) break;
618 //-----------------------------------------------------------------------------
619 bool OSQLParseTreeIterator::traverseTableNames(OSQLTables
& _rTables
)
621 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseTableNames" );
622 if ( m_pParseTree
== NULL
)
625 OSQLParseNode
* pTableName
= NULL
;
627 switch ( m_eStatementType
)
629 case SQL_STATEMENT_SELECT
:
630 getSelect_statement( _rTables
, m_pParseTree
);
633 case SQL_STATEMENT_CREATE_TABLE
:
634 case SQL_STATEMENT_INSERT
:
635 case SQL_STATEMENT_DELETE
:
636 pTableName
= m_pParseTree
->getChild(2);
639 case SQL_STATEMENT_UPDATE
:
640 pTableName
= m_pParseTree
->getChild(1);
648 ::rtl::OUString sTableRange
;
649 traverseOneTableName( _rTables
, pTableName
, sTableRange
);
654 //-----------------------------------------------------------------------------
655 ::rtl::OUString
OSQLParseTreeIterator::getColumnAlias(const OSQLParseNode
* _pDerivedColumn
)
657 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnAlias" );
658 OSL_ENSURE(SQL_ISRULE(_pDerivedColumn
,derived_column
),"No derived column!");
659 ::rtl::OUString sColumnAlias
;
660 if(_pDerivedColumn
->getChild(1)->count() == 2)
661 sColumnAlias
= _pDerivedColumn
->getChild(1)->getChild(1)->getTokenValue();
662 else if(!_pDerivedColumn
->getChild(1)->isRule())
663 sColumnAlias
= _pDerivedColumn
->getChild(1)->getTokenValue();
667 // -----------------------------------------------------------------------------
670 void lcl_getColumnRange( const OSQLParseNode
* _pColumnRef
, const Reference
< XConnection
>& _rxConnection
,
671 ::rtl::OUString
& _out_rColumnName
, ::rtl::OUString
& _out_rTableRange
,
672 const OSQLColumns
* _pSelectColumns
, ::rtl::OUString
& _out_rColumnAliasIfPresent
)
674 _out_rColumnName
= _out_rTableRange
= _out_rColumnAliasIfPresent
= ::rtl::OUString();
675 if ( SQL_ISRULE( _pColumnRef
, column_ref
) )
677 if( _pColumnRef
->count() > 1 )
679 for ( sal_Int32 i
=0; i
<((sal_Int32
)_pColumnRef
->count())-2; ++i
)
680 _pColumnRef
->getChild(i
)->parseNodeToStr( _out_rTableRange
, _rxConnection
, NULL
, sal_False
, sal_False
);
681 _out_rColumnName
= _pColumnRef
->getChild( _pColumnRef
->count()-1 )->getChild(0)->getTokenValue();
684 _out_rColumnName
= _pColumnRef
->getChild(0)->getTokenValue();
686 // look up the column in the select column, to find an possible alias
687 if ( _pSelectColumns
)
689 for ( OSQLColumns::Vector::const_iterator lookupColumn
= _pSelectColumns
->get().begin();
690 lookupColumn
!= _pSelectColumns
->get().end();
694 Reference
< XPropertySet
> xColumn( *lookupColumn
);
697 ::rtl::OUString sName
, sTableName
;
698 xColumn
->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_REALNAME
) ) >>= sName
;
699 xColumn
->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_TABLENAME
) ) >>= sTableName
;
700 if ( sName
== _out_rColumnName
&& sTableName
== _out_rTableRange
)
701 xColumn
->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_NAME
) ) >>= _out_rColumnAliasIfPresent
;
703 catch( const Exception
& )
705 DBG_UNHANDLED_EXCEPTION();
710 else if(SQL_ISRULE(_pColumnRef
,general_set_fct
) || SQL_ISRULE(_pColumnRef
,set_fct_spec
))
712 _pColumnRef
->parseNodeToStr( _out_rColumnName
, _rxConnection
);
714 else if(_pColumnRef
->getNodeType() == SQL_NODE_NAME
)
715 _out_rColumnName
= _pColumnRef
->getTokenValue();
719 // -----------------------------------------------------------------------------
720 void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode
* _pColumnRef
,
721 ::rtl::OUString
& _rColumnName
,
722 ::rtl::OUString
& _rTableRange
) const
724 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnRange" );
725 ::rtl::OUString sDummy
;
726 lcl_getColumnRange( _pColumnRef
, m_pImpl
->m_xConnection
, _rColumnName
, _rTableRange
, NULL
, sDummy
);
729 // -----------------------------------------------------------------------------
730 void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode
* _pColumnRef
,
731 ::rtl::OUString
& _rColumnName
,
732 ::rtl::OUString
& _rTableRange
,
733 ::rtl::OUString
& _out_rColumnAliasIfPresent
) const
735 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnRange" );
736 lcl_getColumnRange( _pColumnRef
, m_pImpl
->m_xConnection
, _rColumnName
, _rTableRange
, &*m_aSelectColumns
, _out_rColumnAliasIfPresent
);
739 //-----------------------------------------------------------------------------
740 void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode
* _pColumnRef
,
741 const Reference
< XConnection
>& _rxConnection
, ::rtl::OUString
& _out_rColumnName
, ::rtl::OUString
& _out_rTableRange
)
743 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnRange" );
744 ::rtl::OUString sDummy
;
745 lcl_getColumnRange( _pColumnRef
, _rxConnection
, _out_rColumnName
, _out_rTableRange
, NULL
, sDummy
);
748 //-----------------------------------------------------------------------------
749 sal_Bool
OSQLParseTreeIterator::getColumnTableRange(const OSQLParseNode
* pNode
, ::rtl::OUString
&rTableRange
) const
751 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnTableRange" );
752 // Ermitteln ob alle Spalten zu einer Tabelle gehoeren
753 if (SQL_ISRULE(pNode
,column_ref
))
755 ::rtl::OUString aColName
, aTableRange
;
756 getColumnRange(pNode
, aColName
, aTableRange
);
757 if (!aTableRange
.getLength()) // keinen gefunden
759 // dann die Spalte in den Tabellen suchen
760 for (ConstOSQLTablesIterator aIter
= m_pImpl
->m_pTables
->begin(); aIter
!= m_pImpl
->m_pTables
->end(); ++aIter
)
762 if (aIter
->second
.is())
766 Reference
< XNameAccess
> xColumns
= aIter
->second
->getColumns();
767 if(xColumns
->hasByName(aColName
))
769 Reference
< XPropertySet
> xColumn
;
770 if (xColumns
->getByName(aColName
) >>= xColumn
)
772 OSL_ENSURE(xColumn
.is(),"Column isn't a propertyset!");
773 aTableRange
= aIter
->first
;
783 if (!aTableRange
.getLength())
788 if (!rTableRange
.getLength())
789 rTableRange
= aTableRange
;
790 else if (rTableRange
!= aTableRange
)
795 for (sal_uInt32 i
= 0, ncount
= pNode
->count(); i
< ncount
; i
++)
797 if (!getColumnTableRange(pNode
->getChild(i
), rTableRange
))
804 //-----------------------------------------------------------------------------
805 void OSQLParseTreeIterator::traverseCreateColumns(const OSQLParseNode
* pSelectNode
)
807 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseCreateColumns" );
808 // aIteratorStatus.Clear();
810 if (!pSelectNode
|| m_eStatementType
!= SQL_STATEMENT_CREATE_TABLE
|| m_pImpl
->m_pTables
->empty())
812 impl_appendError( IParseContext::ERROR_GENERAL
);
815 if (!SQL_ISRULE(pSelectNode
,base_table_element_commalist
))
818 for (sal_uInt32 i
= 0; i
< pSelectNode
->count(); i
++)
820 OSQLParseNode
*pColumnRef
= pSelectNode
->getChild(i
);
822 if (SQL_ISRULE(pColumnRef
,column_def
))
824 ::rtl::OUString aColumnName
;
825 ::rtl::OUString aTypeName
;
826 ::rtl::OUString aTableRange
;
827 sal_Int32 nType
= DataType::VARCHAR
;
829 aColumnName
= pColumnRef
->getChild(0)->getTokenValue();
831 OSQLParseNode
*pDatatype
= pColumnRef
->getChild(1);
832 if (pDatatype
&& SQL_ISRULE(pDatatype
,data_type
))
837 aTypeName
= pDatatype
->getChild(0)->getTokenValue();
838 if (pDatatype
->count() == 4
839 && SQL_ISPUNCTUATION(pDatatype
->getChild(1), "(")
840 && SQL_ISPUNCTUATION(pDatatype
->getChild(3) , ")") )
842 nLen
= pDatatype
->getChild(2)->getTokenValue().toInt32();
845 else if(pDatatype
&& pDatatype
->getNodeType() == SQL_NODE_KEYWORD
)
847 aTypeName
= ::rtl::OUString::createFromAscii("VARCHAR");
850 if (aTypeName
.getLength())
852 //TO DO:Create a new class for create statement to handle field length
853 OParseColumn
* pColumn
= new OParseColumn(aColumnName
,aTypeName
,::rtl::OUString(),
854 ColumnValue::NULLABLE_UNKNOWN
,0,0,nType
,sal_False
,sal_False
,isCaseSensitive());
855 pColumn
->setFunction(sal_False
);
856 pColumn
->setRealName(aColumnName
);
858 Reference
< XPropertySet
> xCol
= pColumn
;
859 m_aCreateColumns
->get().push_back(xCol
);
865 //-----------------------------------------------------------------------------
866 bool OSQLParseTreeIterator::traverseSelectColumnNames(const OSQLParseNode
* pSelectNode
)
868 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseSelectColumnNames" );
869 if ( ( m_pImpl
->m_nIncludeMask
& SelectColumns
) != SelectColumns
)
872 if (!pSelectNode
|| m_eStatementType
!= SQL_STATEMENT_SELECT
|| m_pImpl
->m_pTables
->empty())
874 impl_appendError( IParseContext::ERROR_GENERAL
);
878 if(SQL_ISRULE(pSelectNode
,union_statement
))
880 return traverseSelectColumnNames( pSelectNode
->getChild( 0 ) )
881 /*&& traverseSelectColumnNames( pSelectNode->getChild( 3 ) )*/;
884 static ::rtl::OUString aEmptyString
;
885 // nyi: mehr Pruefung auf korrekte Struktur!
886 if (pSelectNode
->getChild(2)->isRule() && SQL_ISPUNCTUATION(pSelectNode
->getChild(2)->getChild(0),"*"))
889 setSelectColumnName(m_aSelectColumns
,::rtl::OUString::createFromAscii("*"), aEmptyString
,aEmptyString
);
891 else if (SQL_ISRULE(pSelectNode
->getChild(2),scalar_exp_commalist
))
893 // SELECT column[,column] oder SELECT COUNT(*) ...
894 OSQLParseNode
* pSelection
= pSelectNode
->getChild(2);
896 for (sal_uInt32 i
= 0; i
< pSelection
->count(); i
++)
898 OSQLParseNode
*pColumnRef
= pSelection
->getChild(i
);
900 //if (SQL_ISRULE(pColumnRef,select_sublist))
901 if (SQL_ISRULE(pColumnRef
,derived_column
) &&
902 SQL_ISRULE(pColumnRef
->getChild(0),column_ref
) &&
903 pColumnRef
->getChild(0)->count() == 3 &&
904 SQL_ISPUNCTUATION(pColumnRef
->getChild(0)->getChild(2),"*"))
906 // alle Spalten der Tabelle
907 ::rtl::OUString aTableRange
;
908 pColumnRef
->getChild(0)->parseNodeToStr( aTableRange
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
909 setSelectColumnName(m_aSelectColumns
,::rtl::OUString::createFromAscii("*"), aEmptyString
,aTableRange
);
912 else if (SQL_ISRULE(pColumnRef
,derived_column
))
914 ::rtl::OUString
aColumnAlias(getColumnAlias(pColumnRef
)); // kann leer sein
915 ::rtl::OUString sColumnName
;
916 ::rtl::OUString aTableRange
;
917 sal_Int32 nType
= DataType::VARCHAR
;
918 sal_Bool
bFkt(sal_False
);
919 pColumnRef
= pColumnRef
->getChild(0);
921 pColumnRef
->count() == 3 &&
922 SQL_ISPUNCTUATION(pColumnRef
->getChild(0),"(") &&
923 SQL_ISPUNCTUATION(pColumnRef
->getChild(2),")")
925 pColumnRef
= pColumnRef
->getChild(1);
927 if (SQL_ISRULE(pColumnRef
,column_ref
))
929 getColumnRange(pColumnRef
,sColumnName
,aTableRange
);
930 OSL_ENSURE(sColumnName
.getLength(),"Columnname darf nicht leer sein");
932 else /*if (SQL_ISRULE(pColumnRef,general_set_fct) || SQL_ISRULE(pColumnRef,set_fct_spec) ||
933 SQL_ISRULE(pColumnRef,position_exp) || SQL_ISRULE(pColumnRef,extract_exp) ||
934 SQL_ISRULE(pColumnRef,length_exp) || SQL_ISRULE(pColumnRef,char_value_fct)||
935 SQL_ISRULE(pColumnRef,num_value_exp) || SQL_ISRULE(pColumnRef,term))*/
937 /* Funktionsaufruf vorhanden */
938 pColumnRef
->parseNodeToStr( sColumnName
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_True
);
939 ::rtl::OUString sTableRange
;
940 // check if the column is also a parameter
941 traverseORCriteria(pColumnRef
); // num_value_exp
943 // gehoeren alle beteiligten Spalten der Funktion zu einer Tabelle
944 if (m_pImpl
->m_pTables
->size() == 1)
946 aTableRange
= m_pImpl
->m_pTables
->begin()->first
;
950 getColumnTableRange(pColumnRef
,aTableRange
);
952 if ( pColumnRef
->isRule() )
955 if ( SQL_ISRULE(pColumnRef
,num_value_exp
) || SQL_ISRULE(pColumnRef
,term
) || SQL_ISRULE(pColumnRef
,factor
) )
957 nType
= DataType::DOUBLE
;
961 ::rtl::OUString sFunctionName
;
962 if ( SQL_ISRULE(pColumnRef
,length_exp
) )
963 pColumnRef
->getChild(0)->getChild(0)->parseNodeToStr(
964 sFunctionName
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
966 pColumnRef
->getChild(0)->parseNodeToStr(
967 sFunctionName
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
968 nType
= ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName
, &m_rParser
.getContext() );
975 aIteratorStatus.setStatementTooComplex();
979 if(!aColumnAlias
.getLength())
980 aColumnAlias
= sColumnName
;
981 setSelectColumnName(m_aSelectColumns
,sColumnName
,aColumnAlias
,aTableRange
,bFkt
,nType
,SQL_ISRULE(pColumnRef
,general_set_fct
) || SQL_ISRULE(pColumnRef
,set_fct_spec
));
990 //-----------------------------------------------------------------------------
991 bool OSQLParseTreeIterator::traverseOrderByColumnNames(const OSQLParseNode
* pSelectNode
)
993 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseOrderByColumnNames" );
994 traverseByColumnNames( pSelectNode
, sal_True
);
997 //-----------------------------------------------------------------------------
998 void OSQLParseTreeIterator::traverseByColumnNames(const OSQLParseNode
* pSelectNode
,sal_Bool _bOrder
)
1000 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseByColumnNames" );
1001 // aIteratorStatus.Clear();
1003 if (pSelectNode
== NULL
)
1005 //aIteratorStatus.setInvalidStatement();
1009 if (m_eStatementType
!= SQL_STATEMENT_SELECT
)
1011 //aIteratorStatus.setInvalidStatement();
1015 if(SQL_ISRULE(pSelectNode
,union_statement
))
1017 traverseByColumnNames(pSelectNode
->getChild(0),_bOrder
);
1021 OSL_ENSURE(pSelectNode
->count() >= 4,"OSQLParseTreeIterator: error in parse tree!");
1023 OSQLParseNode
* pTableExp
= pSelectNode
->getChild(3);
1024 OSL_ENSURE(pTableExp
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1025 OSL_ENSURE(SQL_ISRULE(pTableExp
,table_exp
),"OSQLParseTreeIterator:table_exp error in parse tree!");
1026 OSL_ENSURE(pTableExp
->count() == 5,"OSQLParseTreeIterator: error in parse tree!");
1028 sal_uInt32 nPos
= ( _bOrder
? 4 : 2 );
1030 OSQLParseNode
* pOptByClause
= pTableExp
->getChild(nPos
);
1031 OSL_ENSURE(pOptByClause
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1032 if ( pOptByClause
->count() == 0 )
1035 OSL_ENSURE(pOptByClause
->count() == 3,"OSQLParseTreeIterator: error in parse tree!");
1037 OSQLParseNode
* pOrderingSpecCommalist
= pOptByClause
->getChild(2);
1038 OSL_ENSURE(pOrderingSpecCommalist
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1039 OSL_ENSURE(!_bOrder
|| SQL_ISRULE(pOrderingSpecCommalist
,ordering_spec_commalist
),"OSQLParseTreeIterator:ordering_spec_commalist error in parse tree!");
1040 OSL_ENSURE(pOrderingSpecCommalist
->count() > 0,"OSQLParseTreeIterator: error in parse tree!");
1042 ::rtl::OUString sColumnName
,aColumnAlias
;
1043 ::rtl::OUString aTableRange
;
1044 sal_uInt32 nCount
= pOrderingSpecCommalist
->count();
1045 for (sal_uInt32 i
= 0; i
< nCount
; ++i
)
1047 OSQLParseNode
* pColumnRef
= pOrderingSpecCommalist
->getChild(i
);
1048 OSL_ENSURE(pColumnRef
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1051 OSL_ENSURE(SQL_ISRULE(pColumnRef
,ordering_spec
),"OSQLParseTreeIterator:ordering_spec error in parse tree!");
1052 OSL_ENSURE(pColumnRef
->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
1054 pColumnRef
= pColumnRef
->getChild(0);
1056 aTableRange
= ::rtl::OUString();
1057 sColumnName
= ::rtl::OUString();
1058 if ( SQL_ISRULE(pColumnRef
,column_ref
) )
1060 // Column-Name (und TableRange):
1061 if(SQL_ISRULE(pColumnRef
,column_ref
))
1062 getColumnRange(pColumnRef
,sColumnName
,aTableRange
);
1063 else // eine Expression
1064 pColumnRef
->parseNodeToStr( sColumnName
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
1066 OSL_ENSURE(sColumnName
.getLength(),"sColumnName darf nicht leer sein");
1069 { // here I found a predicate
1070 pColumnRef
->parseNodeToStr( sColumnName
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
1072 OSL_ENSURE(pColumnRef
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1075 // Ascending/Descending
1076 OSQLParseNode
* pOptAscDesc
= pColumnRef
->getParent()->getChild(1);
1077 OSL_ENSURE(pOptAscDesc
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1079 sal_Bool bAscending
= pOptAscDesc
&& SQL_ISTOKEN(pOptAscDesc
,ASC
);
1080 setOrderByColumnName(sColumnName
, aTableRange
,bAscending
);
1083 setGroupByColumnName(sColumnName
, aTableRange
);
1086 //-----------------------------------------------------------------------------
1087 bool OSQLParseTreeIterator::traverseGroupByColumnNames(const OSQLParseNode
* pSelectNode
)
1089 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseGroupByColumnNames" );
1090 traverseByColumnNames( pSelectNode
, sal_False
);
1091 return !hasErrors();
1094 // -----------------------------------------------------------------------------
1097 ::rtl::OUString
lcl_generateParameterName( const OSQLParseNode
& _rParentNode
, const OSQLParseNode
& _rParamNode
)
1099 ::rtl::OUString
sColumnName( RTL_CONSTASCII_USTRINGPARAM( "param" ) );
1100 const sal_Int32 nCount
= (sal_Int32
)_rParentNode
.count();
1101 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
1103 if ( _rParentNode
.getChild(i
) == &_rParamNode
)
1105 sColumnName
+= ::rtl::OUString::valueOf( i
+1 );
1113 // -----------------------------------------------------------------------------
1114 void OSQLParseTreeIterator::traverseParameters(const OSQLParseNode
* _pNode
)
1116 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseParameters" );
1117 if ( _pNode
== NULL
)
1120 ::rtl::OUString sColumnName
, sTableRange
, aColumnAlias
;
1121 const OSQLParseNode
* pParent
= _pNode
->getParent();
1122 if ( pParent
!= NULL
)
1124 if ( SQL_ISRULE(pParent
,comparison_predicate
) ) // x = X
1126 sal_uInt32 nPos
= 0;
1127 if ( pParent
->getChild(nPos
) == _pNode
)
1129 const OSQLParseNode
* pOther
= pParent
->getChild(nPos
);
1130 if ( SQL_ISRULE( pOther
, column_ref
) )
1131 getColumnRange( pOther
, sColumnName
, sTableRange
, aColumnAlias
);
1133 pOther
->parseNodeToStr( sColumnName
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
1134 } // if ( SQL_ISRULE(pParent,comparison_predicate) ) // x = X
1135 else if ( SQL_ISRULE(pParent
,like_predicate
) )
1137 const OSQLParseNode
* pOther
= pParent
->getChild(0);
1138 if ( SQL_ISRULE( pOther
, column_ref
) )
1139 getColumnRange( pOther
, sColumnName
, sTableRange
, aColumnAlias
);
1141 pOther
->parseNodeToStr( sColumnName
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
1143 else if ( SQL_ISRULE(pParent
,between_predicate
) )
1145 const OSQLParseNode
* pOther
= pParent
->getChild(0);
1146 if ( SQL_ISRULE( pOther
, column_ref
) )
1147 getColumnRange( pOther
, sColumnName
, sTableRange
, aColumnAlias
);
1150 pOther
->parseNodeToStr( sColumnName
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
1151 lcl_generateParameterName( *pParent
, *_pNode
);
1154 else if ( pParent
->getNodeType() == SQL_NODE_COMMALISTRULE
)
1156 lcl_generateParameterName( *pParent
, *_pNode
);
1159 traverseParameter( _pNode
, pParent
, sColumnName
, sTableRange
, aColumnAlias
);
1160 const sal_uInt32 nCount
= _pNode
->count();
1161 for (sal_uInt32 i
= 0; i
< nCount
; ++i
)
1163 const OSQLParseNode
* pChild
= _pNode
->getChild(i
);
1164 traverseParameters( pChild
);
1167 //-----------------------------------------------------------------------------
1168 bool OSQLParseTreeIterator::traverseSelectionCriteria(const OSQLParseNode
* pSelectNode
)
1170 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseSelectionCriteria" );
1171 if ( pSelectNode
== NULL
)
1175 // Parse Tree analysieren (je nach Statement-Typ)
1176 // und Zeiger auf WHERE-Klausel setzen:
1177 OSQLParseNode
* pWhereClause
= NULL
;
1179 if (m_eStatementType
== SQL_STATEMENT_SELECT
)
1181 if(SQL_ISRULE(pSelectNode
,union_statement
))
1183 return traverseSelectionCriteria( pSelectNode
->getChild( 0 ) )
1184 && traverseSelectionCriteria( pSelectNode
->getChild( 3 ) );
1186 OSL_ENSURE(pSelectNode
->count() >= 4,"OSQLParseTreeIterator: error in parse tree!");
1188 OSQLParseNode
* pTableExp
= pSelectNode
->getChild(3);
1189 OSL_ENSURE(pTableExp
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1190 OSL_ENSURE(SQL_ISRULE(pTableExp
,table_exp
),"OSQLParseTreeIterator: error in parse tree!");
1191 OSL_ENSURE(pTableExp
->count() == 5,"OSQLParseTreeIterator: error in parse tree!");
1193 pWhereClause
= pTableExp
->getChild(1);
1194 } else if (SQL_ISRULE(pSelectNode
,update_statement_searched
)) {
1195 OSL_ENSURE(pSelectNode
->count() == 5,"OSQLParseTreeIterator: error in parse tree!");
1196 pWhereClause
= pSelectNode
->getChild(4);
1197 } else if (SQL_ISRULE(pSelectNode
,delete_statement_searched
)) {
1198 OSL_ENSURE(pSelectNode
->count() == 4,"OSQLParseTreeIterator: error in parse tree!");
1199 pWhereClause
= pSelectNode
->getChild(3);
1200 } else if (SQL_ISRULE(pSelectNode
,delete_statement_positioned
)) {
1202 OSL_ASSERT("OSQLParseTreeIterator::getSelectionCriteria: positioned nyi");
1204 // Anderes Statement. Keine Selektionskriterien.
1208 if (! SQL_ISRULE(pWhereClause
,where_clause
)) {
1209 // Die Where Clause ist meistens optional, d. h. es koennte sich auch
1210 // um "optional_where_clause" handeln.
1211 OSL_ENSURE(SQL_ISRULE(pWhereClause
,opt_where_clause
),"OSQLParseTreeIterator: error in parse tree!");
1215 // Wenn es aber eine where_clause ist, dann darf sie nicht leer sein:
1216 OSL_ENSURE(pWhereClause
->count() == 2,"OSQLParseTreeIterator: error in parse tree!");
1218 OSQLParseNode
* pComparisonPredicate
= pWhereClause
->getChild(1);
1219 OSL_ENSURE(pComparisonPredicate
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1222 // Und nun die Vergleichskriterien abarbeiten (rekursiv, alles ist erstmal ein OR-Kriterium):
1225 traverseORCriteria(pComparisonPredicate
);
1227 return !hasErrors();
1230 //-----------------------------------------------------------------------------
1231 void OSQLParseTreeIterator::traverseORCriteria(OSQLParseNode
* pSearchCondition
)
1233 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseORCriteria" );
1237 pSearchCondition
->count() == 3 &&
1238 SQL_ISPUNCTUATION(pSearchCondition
->getChild(0),"(") &&
1239 SQL_ISPUNCTUATION(pSearchCondition
->getChild(2),")")
1242 // Runde Klammern um den Ausdruck
1243 traverseORCriteria(pSearchCondition
->getChild(1));
1244 } else if (SQL_ISRULE(pSearchCondition
,search_condition
) &&
1245 pSearchCondition
->count() == 3 &&
1246 SQL_ISTOKEN(pSearchCondition
->getChild(1),OR
))
1250 for (int i
= 0; i
< 3; i
++) {
1251 if (i
== 1) continue; // Schluesselwort OR ueberspringen
1253 // Ist das erste Element wieder eine OR-Verknuepfung?
1255 SQL_ISRULE(pSearchCondition
->getChild(0),search_condition
) &&
1256 pSearchCondition
->getChild(0)->count() == 3 &&
1257 SQL_ISTOKEN(pSearchCondition
->getChild(0)->getChild(1),OR
))
1259 // Dann rekursiv absteigen ...
1260 traverseORCriteria(pSearchCondition
->getChild(0));
1263 // AND-Kriterien ...
1264 traverseANDCriteria(pSearchCondition
->getChild(i
));
1265 // if (! aIteratorStatus.IsSuccessful()) break;
1268 // if (! aIteratorStatus.IsSuccessful()) break;
1271 // Nur *ein* Kriterium oder eine AND-Verknuepfung von Kriterien.
1272 // Direkt die AND-Kriterien behandeln.
1273 traverseANDCriteria(pSearchCondition
);
1274 // if (! aIteratorStatus.IsSuccessful()) return;
1277 // Fehler einfach weiterreichen.
1280 //-----------------------------------------------------------------------------
1281 void OSQLParseTreeIterator::traverseANDCriteria(OSQLParseNode
* pSearchCondition
)
1283 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseANDCriteria" );
1287 SQL_ISRULE(pSearchCondition
,boolean_primary
) &&
1288 pSearchCondition
->count() == 3 &&
1289 SQL_ISPUNCTUATION(pSearchCondition
->getChild(0),"(") &&
1290 SQL_ISPUNCTUATION(pSearchCondition
->getChild(2),")")
1294 traverseANDCriteria(pSearchCondition
->getChild(1));
1296 // Das erste Element ist eine OR-Verknuepfung
1297 else if ( SQL_ISRULE(pSearchCondition
,search_condition
) && pSearchCondition
->count() == 3 )
1299 // Dann rekursiv absteigen (dieselbe Row benutzen) ...
1300 traverseORCriteria(pSearchCondition
->getChild(0));
1301 // if (! aIteratorStatus.IsSuccessful())
1304 // Und mit dem rechten Child weitermachen:
1305 traverseANDCriteria(pSearchCondition
->getChild(2));
1307 // Das erste Element ist (wieder) eine AND-Verknuepfung
1308 else if ( SQL_ISRULE(pSearchCondition
,boolean_term
) && pSearchCondition
->count() == 3 )
1310 // Dann rekursiv absteigen (dieselbe Row benutzen) ...
1311 traverseANDCriteria(pSearchCondition
->getChild(0));
1312 // if (! aIteratorStatus.IsSuccessful())
1315 // Und mit dem rechten Child weitermachen:
1316 traverseANDCriteria(pSearchCondition
->getChild(2));
1318 // Sonst einzelne Suchkriterien wie =, !=, ..., LIKE, IS NULL usw. behandeln:
1319 else if (SQL_ISRULE(pSearchCondition
,comparison_predicate
) )
1321 ::rtl::OUString aValue
;
1322 pSearchCondition
->getChild(2)->parseNodeToStr( aValue
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
1323 traverseOnePredicate(pSearchCondition
->getChild(0),aValue
,pSearchCondition
->getChild(2));
1324 // if (! aIteratorStatus.IsSuccessful())
1327 else if (SQL_ISRULE(pSearchCondition
,like_predicate
) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/)
1329 OSL_ENSURE(pSearchCondition
->count() >= 4,"OSQLParseTreeIterator: error in parse tree!");
1331 sal_Int32 nCurentPos
= pSearchCondition
->count()-2;
1333 OSQLParseNode
* pNum_value_exp
= pSearchCondition
->getChild(nCurentPos
);
1334 OSQLParseNode
* pOptEscape
= pSearchCondition
->getChild(nCurentPos
+1);
1336 OSL_ENSURE(pNum_value_exp
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1337 OSL_ENSURE(pOptEscape
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1339 if (pOptEscape
->count() != 0)
1341 // aIteratorStatus.setStatementTooComplex();
1345 ::rtl::OUString aValue
;
1346 OSQLParseNode
* pParam
= NULL
;
1347 if (SQL_ISRULE(pNum_value_exp
,parameter
))
1348 pParam
= pNum_value_exp
;
1349 else if(pNum_value_exp
->isToken())
1351 aValue
= pNum_value_exp
->getTokenValue();
1354 pNum_value_exp
->parseNodeToStr( aValue
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
1355 pParam
= pNum_value_exp
;
1358 traverseOnePredicate(pSearchCondition
->getChild(0),aValue
,pParam
);
1359 // if (! aIteratorStatus.IsSuccessful())
1362 else if (SQL_ISRULE(pSearchCondition
,in_predicate
))
1364 OSL_ENSURE(pSearchCondition
->count() == 4,"OSQLParseTreeIterator: error in parse tree!");
1366 traverseORCriteria(pSearchCondition
->getChild(0));
1367 // if (! aIteratorStatus.IsSuccessful()) return;
1369 OSQLParseNode
* pChild
= pSearchCondition
->getChild(3);
1370 if ( SQL_ISRULE(pChild
->getChild(0),subquery
) )
1372 traverseTableNames( *m_pImpl
->m_pSubTables
);
1373 traverseSelectionCriteria(pChild
->getChild(0)->getChild(1));
1376 { // '(' value_exp_commalist ')'
1377 pChild
= pChild
->getChild(1);
1378 sal_Int32 nCount
= pChild
->count();
1379 for (sal_Int32 i
=0; i
< nCount
; ++i
)
1381 traverseANDCriteria(pChild
->getChild(i
));
1385 else if (SQL_ISRULE(pSearchCondition
,test_for_null
) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/)
1387 OSL_ENSURE(pSearchCondition
->count() >= 3,"OSQLParseTreeIterator: error in parse tree!");
1388 OSL_ENSURE(SQL_ISTOKEN(pSearchCondition
->getChild(1),IS
),"OSQLParseTreeIterator: error in parse tree!");
1390 ::rtl::OUString aString
;
1391 traverseOnePredicate(pSearchCondition
->getChild(0),aString
,NULL
);
1392 // if (! aIteratorStatus.IsSuccessful()) return;
1394 else if (SQL_ISRULE(pSearchCondition
,num_value_exp
) || SQL_ISRULE(pSearchCondition
,term
))
1396 ::rtl::OUString aString
;
1397 traverseOnePredicate(pSearchCondition
->getChild(0),aString
,pSearchCondition
->getChild(0));
1398 traverseOnePredicate(pSearchCondition
->getChild(2),aString
,pSearchCondition
->getChild(2));
1400 // Fehler einfach weiterreichen.
1402 //-----------------------------------------------------------------------------
1403 void OSQLParseTreeIterator::traverseParameter(const OSQLParseNode
* _pParseNode
1404 ,const OSQLParseNode
* _pColumnRef
1405 ,const ::rtl::OUString
& _aColumnName
1406 ,const ::rtl::OUString
& _aTableRange
1407 ,const ::rtl::OUString
& _rColumnAlias
)
1409 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseParameter" );
1410 if ( !SQL_ISRULE( _pParseNode
, parameter
) )
1413 if ( ( m_pImpl
->m_nIncludeMask
& Parameters
) != Parameters
)
1414 // parameters not to be included in the traversal
1417 OSL_ENSURE(_pParseNode
->count() > 0,"OSQLParseTreeIterator: error in parse tree!");
1418 OSQLParseNode
* pMark
= _pParseNode
->getChild(0);
1419 ::rtl::OUString sParameterName
;
1421 if (SQL_ISPUNCTUATION(pMark
,"?"))
1423 sParameterName
= _rColumnAlias
.getLength()
1425 : _aColumnName
.getLength()
1427 : ::rtl::OUString::createFromAscii("?");
1429 else if (SQL_ISPUNCTUATION(pMark
,":"))
1431 sParameterName
= _pParseNode
->getChild(1)->getTokenValue();
1433 else if (SQL_ISPUNCTUATION(pMark
,"["))
1435 sParameterName
= _pParseNode
->getChild(1)->getTokenValue();
1439 OSL_ASSERT("OSQLParseTreeIterator: error in parse tree!");
1442 // found a parameter
1443 if ( _pColumnRef
&& (SQL_ISRULE(_pColumnRef
,general_set_fct
) || SQL_ISRULE(_pColumnRef
,set_fct_spec
)) )
1444 {// found a function as column_ref
1445 ::rtl::OUString sFunctionName
;
1446 _pColumnRef
->getChild(0)->parseNodeToStr( sFunctionName
, m_pImpl
->m_xConnection
, NULL
, sal_False
, sal_False
);
1447 sal_Int32 nType
= ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName
, &m_rParser
.getContext() );
1449 OParseColumn
* pColumn
= new OParseColumn( sParameterName
,
1452 ColumnValue::NULLABLE_UNKNOWN
,
1459 pColumn
->setFunction(sal_True
);
1460 pColumn
->setAggregateFunction(sal_True
);
1461 pColumn
->setRealName(sFunctionName
);
1462 m_aParameters
->get().push_back(pColumn
);
1466 sal_Bool bNotFound
= sal_True
;
1467 OSQLColumns::Vector::const_iterator aIter
= ::connectivity::find(
1468 m_aSelectColumns
->get().begin(),
1469 m_aSelectColumns
->get().end(),
1470 _aColumnName
,::comphelper::UStringMixEqual( isCaseSensitive() )
1472 if(aIter
!= m_aSelectColumns
->get().end())
1474 OParseColumn
* pNewColumn
= new OParseColumn(*aIter
,isCaseSensitive());
1475 pNewColumn
->setName(sParameterName
);
1476 pNewColumn
->setRealName(_aColumnName
);
1477 m_aParameters
->get().push_back(pNewColumn
);
1478 bNotFound
= sal_False
;
1480 else if(_aColumnName
.getLength())// search in the tables for the right one
1483 Reference
<XPropertySet
> xColumn
= findColumn( _aColumnName
, _aTableRange
, true );
1487 OParseColumn
* pNewColumn
= new OParseColumn(xColumn
,isCaseSensitive());
1488 pNewColumn
->setName(sParameterName
);
1489 pNewColumn
->setRealName(_aColumnName
);
1490 m_aParameters
->get().push_back(pNewColumn
);
1491 bNotFound
= sal_False
;
1496 sal_Int32 nType
= DataType::VARCHAR
;
1497 OSQLParseNode
* pParent
= _pColumnRef
? _pColumnRef
->getParent() : NULL
;
1498 if ( pParent
&& (SQL_ISRULE(pParent
,general_set_fct
) || SQL_ISRULE(pParent
,set_fct_spec
)) )
1500 const sal_uInt32 nCount
= _pColumnRef
->count();
1502 for(; i
< nCount
;++i
)
1504 if ( _pColumnRef
->getChild(i
) == _pParseNode
)
1507 nType
= ::connectivity::OSQLParser::getFunctionParameterType( pParent
->getChild(0)->getTokenID(), i
+1);
1510 ::rtl::OUString
aNewColName( getUniqueColumnName( sParameterName
) );
1512 OParseColumn
* pColumn
= new OParseColumn(aNewColName
,
1515 ColumnValue::NULLABLE_UNKNOWN
,
1521 isCaseSensitive() );
1522 pColumn
->setName(aNewColName
);
1523 pColumn
->setRealName(sParameterName
);
1524 m_aParameters
->get().push_back(pColumn
);
1528 //-----------------------------------------------------------------------------
1529 void OSQLParseTreeIterator::traverseOnePredicate(
1530 OSQLParseNode
* pColumnRef
,
1531 ::rtl::OUString
& rValue
,
1532 OSQLParseNode
* pParseNode
)
1534 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseOnePredicate" );
1538 // Column-Name (und TableRange):
1539 ::rtl::OUString aColumnName
, aTableRange
, sColumnAlias
;
1540 getColumnRange( pColumnRef
, aColumnName
, aTableRange
, sColumnAlias
);
1542 ::rtl::OUString aName
;
1544 /*if (SQL_ISRULE(pParseNode,parameter))
1545 traverseParameter( pParseNode, pColumnRef, aColumnName, aTableRange, sColumnAlias );
1546 else */if (SQL_ISRULE(pParseNode
,column_ref
))// Column-Name (und TableRange):
1547 getColumnRange(pParseNode
,aName
,rValue
);
1550 traverseORCriteria(pParseNode
);
1551 // if (! aIteratorStatus.IsSuccessful()) return;
1555 //-----------------------------------------------------------------------------
1556 void OSQLParseTreeIterator::traverseSome( sal_uInt32 _nIncludeMask
)
1558 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseSome" );
1559 impl_traverse( _nIncludeMask
);
1562 //-----------------------------------------------------------------------------
1563 void OSQLParseTreeIterator::traverseAll()
1565 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseAll" );
1566 impl_traverse( All
);
1569 //-----------------------------------------------------------------------------
1570 void OSQLParseTreeIterator::impl_traverse( sal_uInt32 _nIncludeMask
)
1572 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_traverse" );
1574 m_pImpl
->m_nIncludeMask
= _nIncludeMask
;
1576 if ( !traverseTableNames( *m_pImpl
->m_pTables
) )
1579 switch ( m_eStatementType
)
1581 case SQL_STATEMENT_SELECT
:
1583 const OSQLParseNode
* pSelectNode
= m_pParseTree
;
1584 traverseParameters( pSelectNode
);
1585 if ( !traverseSelectColumnNames( pSelectNode
)
1586 || !traverseOrderByColumnNames( pSelectNode
)
1587 || !traverseGroupByColumnNames( pSelectNode
)
1588 || !traverseSelectionCriteria( pSelectNode
)
1593 case SQL_STATEMENT_CREATE_TABLE
:
1595 //0 | 1 | 2 |3| 4 |5
1596 //create table sc.foo ( a char(20), b char )
1597 const OSQLParseNode
* pCreateNode
= m_pParseTree
->getChild(4);
1598 traverseCreateColumns(pCreateNode
);
1601 case SQL_STATEMENT_INSERT
:
1604 OSL_ENSURE( false, "OSQLParseTreeIterator::traverseAll: not yet implemented for this statement type!" );
1609 // Dummy-Implementationen:
1611 //-----------------------------------------------------------------------------
1612 OSQLTable
OSQLParseTreeIterator::impl_createTableObject( const ::rtl::OUString
& rTableName
,
1613 const ::rtl::OUString
& rCatalogName
, const ::rtl::OUString
& rSchemaName
)
1615 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_createTableObject" );
1616 OSL_PRECOND( m_eStatementType
== SQL_STATEMENT_CREATE_TABLE
,
1617 "OSQLParseTreeIterator::impl_createTableObject: only to be called for CREATE TABLE statements!" );
1618 // (in all other cases, m_pTables is to contain the table objects as obtained from the tables
1619 // container of the connection (m_xTablesContainer)
1621 OSQLTable aReturnTable
= new OTable(
1625 ::rtl::OUString::createFromAscii("Table"),
1626 ::rtl::OUString::createFromAscii("New Created Table"),
1630 return aReturnTable
;
1632 //-----------------------------------------------------------------------------
1633 void OSQLParseTreeIterator::appendColumns(::vos::ORef
<OSQLColumns
>& _rColumns
,const ::rtl::OUString
& _rTableAlias
,const OSQLTable
& _rTable
)
1635 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::appendColumns" );
1640 Reference
<XNameAccess
> xColumns
= _rTable
->getColumns();
1641 if ( !xColumns
.is() )
1644 Sequence
< ::rtl::OUString
> aColNames
= xColumns
->getElementNames();
1645 const ::rtl::OUString
* pBegin
= aColNames
.getConstArray();
1646 const ::rtl::OUString
* pEnd
= pBegin
+ aColNames
.getLength();
1648 for(;pBegin
!= pEnd
;++pBegin
)
1651 ::rtl::OUString
aName(getUniqueColumnName(*pBegin
));
1652 Reference
< XPropertySet
> xColumn
;
1653 if(xColumns
->hasByName(*pBegin
) && (xColumns
->getByName(*pBegin
) >>= xColumn
) && xColumn
.is())
1655 OParseColumn
* pColumn
= new OParseColumn(aName
1656 , getString(xColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME
)))
1657 , getString(xColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE
)))
1658 , getINT32(xColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE
)))
1659 , getINT32(xColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION
)))
1660 , getINT32(xColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE
)))
1661 , getINT32(xColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE
)))
1662 , getBOOL(xColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT
)))
1663 , getBOOL(xColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY
)))
1664 , isCaseSensitive() );
1666 pColumn
->setTableName(_rTableAlias
);
1667 pColumn
->setRealName(*pBegin
);
1668 Reference
< XPropertySet
> xCol
= pColumn
;
1669 _rColumns
->get().push_back(xCol
);
1672 impl_appendError( IParseContext::ERROR_INVALID_COLUMN
, pBegin
, &_rTableAlias
);
1675 //-----------------------------------------------------------------------------
1676 void OSQLParseTreeIterator::setSelectColumnName(::vos::ORef
<OSQLColumns
>& _rColumns
,const ::rtl::OUString
& rColumnName
,const ::rtl::OUString
& rColumnAlias
, const ::rtl::OUString
& rTableRange
,sal_Bool bFkt
,sal_Int32 _nType
,sal_Bool bAggFkt
)
1678 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setSelectColumnName" );
1679 if(rColumnName
.toChar() == '*' && !rTableRange
.getLength())
1681 OSL_ENSURE(_rColumns
== m_aSelectColumns
,"Invalid columns used here!");
1682 for(ConstOSQLTablesIterator aIter
= m_pImpl
->m_pTables
->begin(); aIter
!= m_pImpl
->m_pTables
->end();++aIter
)
1683 appendColumns(_rColumns
,aIter
->first
,aIter
->second
);
1685 else if( rColumnName
.toChar() == '*' && rTableRange
.getLength() )
1686 { // SELECT <table>.*
1687 OSL_ENSURE(_rColumns
== m_aSelectColumns
,"Invalid columns used here!");
1688 ConstOSQLTablesIterator aFind
= m_pImpl
->m_pTables
->find(rTableRange
);
1690 if(aFind
!= m_pImpl
->m_pTables
->end())
1691 appendColumns(_rColumns
,rTableRange
,aFind
->second
);
1693 else if ( !rTableRange
.getLength() )
1694 { // SELECT <something> ...
1695 // without table specified
1698 Reference
< XPropertySet
> xNewColumn
;
1700 for ( OSQLTablesIterator aIter
= m_pImpl
->m_pTables
->begin(); aIter
!= m_pImpl
->m_pTables
->end(); ++aIter
)
1702 if ( !aIter
->second
.is() )
1705 Reference
<XNameAccess
> xColumns
= aIter
->second
->getColumns();
1706 Reference
< XPropertySet
> xColumn
;
1707 if ( !xColumns
->hasByName( rColumnName
)
1708 || !( xColumns
->getByName( rColumnName
) >>= xColumn
)
1712 ::rtl::OUString
aNewColName(getUniqueColumnName(rColumnAlias
));
1714 OParseColumn
* pColumn
= new OParseColumn(xColumn
,isCaseSensitive());
1715 xNewColumn
= pColumn
;
1716 pColumn
->setTableName(aIter
->first
);
1717 pColumn
->setName(aNewColName
);
1718 pColumn
->setRealName(rColumnName
);
1723 if ( !xNewColumn
.is() )
1725 // no function (due to the above !bFkt), no existing column
1726 // => assume an expression
1727 ::rtl::OUString
aNewColName( getUniqueColumnName( rColumnAlias
) );
1728 // did not find a column with this name in any of the tables
1729 OParseColumn
* pColumn
= new OParseColumn(
1731 ::rtl::OUString::createFromAscii( "VARCHAR" ),
1732 // TODO: does this match with _nType?
1733 // Or should be fill this from the getTypeInfo of the connection?
1735 ColumnValue::NULLABLE_UNKNOWN
,
1744 xNewColumn
= pColumn
;
1745 pColumn
->setRealName( rColumnName
);
1748 _rColumns
->get().push_back( xNewColumn
);
1752 ::rtl::OUString
aNewColName(getUniqueColumnName(rColumnAlias
));
1754 OParseColumn
* pColumn
= new OParseColumn(aNewColName
,::rtl::OUString(),::rtl::OUString(),
1755 ColumnValue::NULLABLE_UNKNOWN
,0,0,_nType
,sal_False
,sal_False
,isCaseSensitive());
1756 pColumn
->setFunction(sal_True
);
1757 pColumn
->setAggregateFunction(bAggFkt
);
1758 pColumn
->setRealName(rColumnName
);
1760 Reference
< XPropertySet
> xCol
= pColumn
;
1761 _rColumns
->get().push_back(xCol
);
1764 else // ColumnName und Tablename vorhanden
1766 ConstOSQLTablesIterator aFind
= m_pImpl
->m_pTables
->find(rTableRange
);
1768 sal_Bool bError
= sal_False
;
1769 if (aFind
!= m_pImpl
->m_pTables
->end() && aFind
->second
.is())
1773 ::rtl::OUString
aNewColName(getUniqueColumnName(rColumnAlias
));
1775 OParseColumn
* pColumn
= new OParseColumn(aNewColName
,::rtl::OUString(),::rtl::OUString(),
1776 ColumnValue::NULLABLE_UNKNOWN
,0,0,_nType
,sal_False
,sal_False
,isCaseSensitive());
1777 pColumn
->setFunction(sal_True
);
1778 pColumn
->setAggregateFunction(bAggFkt
);
1779 pColumn
->setRealName(rColumnName
);
1780 pColumn
->setTableName(aFind
->first
);
1782 Reference
< XPropertySet
> xCol
= pColumn
;
1783 _rColumns
->get().push_back(xCol
);
1787 Reference
< XPropertySet
> xColumn
;
1788 if (aFind
->second
->getColumns()->hasByName(rColumnName
) && (aFind
->second
->getColumns()->getByName(rColumnName
) >>= xColumn
))
1790 ::rtl::OUString
aNewColName(getUniqueColumnName(rColumnAlias
));
1792 OParseColumn
* pColumn
= new OParseColumn(xColumn
,isCaseSensitive());
1793 pColumn
->setName(aNewColName
);
1794 pColumn
->setRealName(rColumnName
);
1795 pColumn
->setTableName(aFind
->first
);
1797 Reference
< XPropertySet
> xCol
= pColumn
;
1798 _rColumns
->get().push_back(xCol
);
1807 // Tabelle existiert nicht oder Feld nicht vorhanden
1810 ::rtl::OUString
aNewColName(getUniqueColumnName(rColumnAlias
));
1812 OParseColumn
* pColumn
= new OParseColumn(aNewColName
,::rtl::OUString(),::rtl::OUString(),
1813 ColumnValue::NULLABLE_UNKNOWN
,0,0,DataType::VARCHAR
,sal_False
,sal_False
,isCaseSensitive());
1814 pColumn
->setFunction(sal_True
);
1815 pColumn
->setAggregateFunction(bAggFkt
);
1817 Reference
< XPropertySet
> xCol
= pColumn
;
1818 _rColumns
->get().push_back(xCol
);
1822 //-----------------------------------------------------------------------------
1823 ::rtl::OUString
OSQLParseTreeIterator::getUniqueColumnName(const ::rtl::OUString
& rColumnName
) const
1825 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getUniqueColumnName" );
1826 ::rtl::OUString
aAlias(rColumnName
);
1828 OSQLColumns::Vector::const_iterator aIter
= find(
1829 m_aSelectColumns
->get().begin(),
1830 m_aSelectColumns
->get().end(),
1832 ::comphelper::UStringMixEqual( isCaseSensitive() )
1835 while(aIter
!= m_aSelectColumns
->get().end())
1837 (aAlias
= rColumnName
) += ::rtl::OUString::valueOf(i
++);
1839 m_aSelectColumns
->get().begin(),
1840 m_aSelectColumns
->get().end(),
1842 ::comphelper::UStringMixEqual( isCaseSensitive() )
1847 //-----------------------------------------------------------------------------
1848 void OSQLParseTreeIterator::setOrderByColumnName(const ::rtl::OUString
& rColumnName
, const ::rtl::OUString
& rTableRange
,sal_Bool bAscending
)
1850 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setOrderByColumnName" );
1851 Reference
<XPropertySet
> xColumn
= findColumn( rColumnName
, rTableRange
, false );
1853 m_aOrderColumns
->get().push_back(new OOrderColumn(xColumn
,isCaseSensitive(),bAscending
));
1856 sal_Int32 nId
= rColumnName
.toInt32();
1857 if ( nId
> 0 && nId
< static_cast<sal_Int32
>(m_aSelectColumns
->get().size()) )
1858 m_aOrderColumns
->get().push_back(new OOrderColumn((m_aSelectColumns
->get())[nId
-1],isCaseSensitive(),bAscending
));
1861 #ifdef SQL_TEST_PARSETREEITERATOR
1862 cout
<< "OSQLParseTreeIterator::setOrderByColumnName: "
1863 << (const char *) rColumnName
<< ", "
1864 << (const char *) rTableRange
<< ", "
1865 << (bAscending
? "sal_True" : "sal_False")
1869 //-----------------------------------------------------------------------------
1870 void OSQLParseTreeIterator::setGroupByColumnName(const ::rtl::OUString
& rColumnName
, const ::rtl::OUString
& rTableRange
)
1872 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setGroupByColumnName" );
1873 Reference
<XPropertySet
> xColumn
= findColumn( rColumnName
, rTableRange
, false );
1875 m_aGroupColumns
->get().push_back(new OParseColumn(xColumn
,isCaseSensitive()));
1878 sal_Int32 nId
= rColumnName
.toInt32();
1879 if ( nId
> 0 && nId
< static_cast<sal_Int32
>(m_aSelectColumns
->get().size()) )
1880 m_aGroupColumns
->get().push_back(new OParseColumn((m_aSelectColumns
->get())[nId
-1],isCaseSensitive()));
1883 #ifdef SQL_TEST_PARSETREEITERATOR
1884 cout
<< "OSQLParseTreeIterator::setOrderByColumnName: "
1885 << (const char *) rColumnName
<< ", "
1886 << (const char *) rTableRange
<< ", "
1887 << (bAscending
? "sal_True" : "sal_False")
1892 //-----------------------------------------------------------------------------
1893 const OSQLParseNode
* OSQLParseTreeIterator::getWhereTree() const
1895 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getWhereTree" );
1901 // Parse Tree analysieren (je nach Statement-Typ)
1902 // und Zeiger auf WHERE-Klausel setzen:
1903 OSQLParseNode
* pWhereClause
= NULL
;
1904 if(getStatementType() == SQL_STATEMENT_SELECT
)
1906 OSL_ENSURE(m_pParseTree
->count() >= 4,"ParseTreeIterator: error in parse tree!");
1907 OSQLParseNode
* pTableExp
= m_pParseTree
->getChild(3);
1908 OSL_ENSURE(pTableExp
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1909 OSL_ENSURE(SQL_ISRULE(pTableExp
,table_exp
),"OSQLParseTreeIterator: error in parse tree!");
1910 OSL_ENSURE(pTableExp
->count() == 5,"OSQLParseTreeIterator: error in parse tree!");
1912 pWhereClause
= pTableExp
->getChild(1);
1914 else if (SQL_ISRULE(m_pParseTree
,update_statement_searched
) ||
1915 SQL_ISRULE(m_pParseTree
,delete_statement_searched
))
1917 pWhereClause
= m_pParseTree
->getChild(m_pParseTree
->count()-1);
1919 if(pWhereClause
->count() != 2)
1920 pWhereClause
= NULL
;
1921 return pWhereClause
;
1924 //-----------------------------------------------------------------------------
1925 const OSQLParseNode
* OSQLParseTreeIterator::getOrderTree() const
1927 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getOrderTree" );
1930 if (!m_pParseTree
|| getStatementType() != SQL_STATEMENT_SELECT
)
1933 // Parse Tree analysieren (je nach Statement-Typ)
1934 // und Zeiger auf ORDER-Klausel setzen:
1935 OSQLParseNode
* pOrderClause
= NULL
;
1936 OSL_ENSURE(m_pParseTree
->count() >= 4,"ParseTreeIterator: error in parse tree!");
1937 OSQLParseNode
* pTableExp
= m_pParseTree
->getChild(3);
1938 OSL_ENSURE(pTableExp
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1939 OSL_ENSURE(SQL_ISRULE(pTableExp
,table_exp
),"OSQLParseTreeIterator: error in parse tree!");
1940 OSL_ENSURE(pTableExp
->count() == 5,"OSQLParseTreeIterator: error in parse tree!");
1942 pOrderClause
= pTableExp
->getChild(4);
1943 // Wenn es aber eine order_by ist, dann darf sie nicht leer sein:
1944 if(pOrderClause
->count() != 3)
1945 pOrderClause
= NULL
;
1946 return pOrderClause
;
1948 //-----------------------------------------------------------------------------
1949 const OSQLParseNode
* OSQLParseTreeIterator::getGroupByTree() const
1951 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getGroupByTree" );
1952 if (!m_pParseTree
|| getStatementType() != SQL_STATEMENT_SELECT
)
1955 // Parse Tree analysieren (je nach Statement-Typ)
1956 // und Zeiger auf ORDER-Klausel setzen:
1957 OSQLParseNode
* pGroupClause
= NULL
;
1958 OSL_ENSURE(m_pParseTree
->count() >= 4,"ParseTreeIterator: error in parse tree!");
1959 OSQLParseNode
* pTableExp
= m_pParseTree
->getChild(3);
1960 OSL_ENSURE(pTableExp
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1961 OSL_ENSURE(SQL_ISRULE(pTableExp
,table_exp
),"OSQLParseTreeIterator: error in parse tree!");
1962 OSL_ENSURE(pTableExp
->count() == 5,"OSQLParseTreeIterator: error in parse tree!");
1964 pGroupClause
= pTableExp
->getChild(2);
1965 // Wenn es aber eine order_by ist, dann darf sie nicht leer sein:
1966 if(pGroupClause
->count() != 3)
1967 pGroupClause
= NULL
;
1968 return pGroupClause
;
1970 //-----------------------------------------------------------------------------
1971 const OSQLParseNode
* OSQLParseTreeIterator::getHavingTree() const
1973 if (!m_pParseTree
|| getStatementType() != SQL_STATEMENT_SELECT
)
1976 // Parse Tree analysieren (je nach Statement-Typ)
1977 // und Zeiger auf ORDER-Klausel setzen:
1978 OSQLParseNode
* pHavingClause
= NULL
;
1979 OSL_ENSURE(m_pParseTree
->count() >= 4,"ParseTreeIterator: error in parse tree!");
1980 OSQLParseNode
* pTableExp
= m_pParseTree
->getChild(3);
1981 OSL_ENSURE(pTableExp
!= NULL
,"OSQLParseTreeIterator: error in parse tree!");
1982 OSL_ENSURE(SQL_ISRULE(pTableExp
,table_exp
),"OSQLParseTreeIterator: error in parse tree!");
1983 OSL_ENSURE(pTableExp
->count() == 5,"OSQLParseTreeIterator: error in parse tree!");
1985 pHavingClause
= pTableExp
->getChild(3);
1986 // Wenn es aber eine order_by ist, dann darf sie nicht leer sein:
1987 if(pHavingClause
->count() < 1)
1988 pHavingClause
= NULL
;
1989 return pHavingClause
;
1991 // -----------------------------------------------------------------------------
1992 sal_Bool
OSQLParseTreeIterator::isTableNode(const OSQLParseNode
* _pTableNode
) const
1994 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::isTableNode" );
1995 return _pTableNode
&& (SQL_ISRULE(_pTableNode
,catalog_name
) ||
1996 SQL_ISRULE(_pTableNode
,schema_name
) ||
1997 SQL_ISRULE(_pTableNode
,table_name
));
1999 // -----------------------------------------------------------------------------
2000 const OSQLParseNode
* OSQLParseTreeIterator::getSimpleWhereTree() const
2002 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleWhereTree" );
2003 const OSQLParseNode
* pNode
= getWhereTree();
2004 return pNode
? pNode
->getChild(1) : NULL
;
2006 // -----------------------------------------------------------------------------
2007 const OSQLParseNode
* OSQLParseTreeIterator::getSimpleOrderTree() const
2009 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleOrderTree" );
2010 const OSQLParseNode
* pNode
= getOrderTree();
2011 return pNode
? pNode
->getChild(2) : NULL
;
2013 // -----------------------------------------------------------------------------
2014 const OSQLParseNode
* OSQLParseTreeIterator::getSimpleGroupByTree() const
2016 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleGroupByTree" );
2017 const OSQLParseNode
* pNode
= getGroupByTree();
2018 return pNode
? pNode
->getChild(2) : NULL
;
2020 // -----------------------------------------------------------------------------
2021 const OSQLParseNode
* OSQLParseTreeIterator::getSimpleHavingTree() const
2023 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleHavingTree" );
2024 const OSQLParseNode
* pNode
= getHavingTree();
2025 return pNode
? pNode
->getChild(1) : NULL
;
2028 // -----------------------------------------------------------------------------
2029 Reference
< XPropertySet
> OSQLParseTreeIterator::findColumn( const ::rtl::OUString
& rColumnName
, const ::rtl::OUString
& rTableRange
, bool _bLookInSubTables
)
2031 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::findColumn" );
2032 Reference
< XPropertySet
> xColumn
= findColumn( *m_pImpl
->m_pTables
, rColumnName
, rTableRange
);
2033 if ( !xColumn
.is() && _bLookInSubTables
)
2034 xColumn
= findColumn( *m_pImpl
->m_pSubTables
, rColumnName
, rTableRange
);
2038 // -----------------------------------------------------------------------------
2039 Reference
< XPropertySet
> OSQLParseTreeIterator::findColumn(const OSQLTables
& _rTables
,const ::rtl::OUString
& rColumnName
, const ::rtl::OUString
& rTableRange
)
2041 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::findColumn" );
2042 Reference
< XPropertySet
> xColumn
;
2043 if ( rTableRange
.getLength() )
2045 ConstOSQLTablesIterator aFind
= _rTables
.find(rTableRange
);
2047 if ( aFind
!= _rTables
.end()
2048 && aFind
->second
.is()
2049 && aFind
->second
->getColumns().is()
2050 && aFind
->second
->getColumns()->hasByName(rColumnName
) )
2051 aFind
->second
->getColumns()->getByName(rColumnName
) >>= xColumn
;
2053 if ( !xColumn
.is() )
2055 OSQLTables::const_iterator aEnd
= _rTables
.end();
2056 for(OSQLTables::const_iterator aIter
= _rTables
.begin(); aIter
!= aEnd
; ++aIter
)
2058 if ( aIter
->second
.is() )
2060 Reference
<XNameAccess
> xColumns
= aIter
->second
->getColumns();
2061 if( xColumns
.is() && xColumns
->hasByName(rColumnName
) && (xColumns
->getByName(rColumnName
) >>= xColumn
) )
2063 OSL_ENSURE(xColumn
.is(),"Column isn't a propertyset!");
2064 break; // diese Column darf nur einmal vorkommen
2072 // -----------------------------------------------------------------------------
2073 void OSQLParseTreeIterator::impl_appendError( IParseContext::ErrorCode _eError
, const ::rtl::OUString
* _pReplaceToken1
, const ::rtl::OUString
* _pReplaceToken2
)
2075 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_appendError" );
2076 ::rtl::OUString sErrorMessage
= m_rParser
.getContext().getErrorMessage( _eError
);
2077 if ( _pReplaceToken1
)
2079 bool bTwoTokens
= ( _pReplaceToken2
!= NULL
);
2080 const sal_Char
* pPlaceHolder1
= bTwoTokens
? "#1" : "#";
2081 const ::rtl::OUString sPlaceHolder1
= ::rtl::OUString::createFromAscii( pPlaceHolder1
);
2083 sErrorMessage
= sErrorMessage
.replaceAt( sErrorMessage
.indexOf( sPlaceHolder1
), sPlaceHolder1
.getLength(), *_pReplaceToken1
);
2084 if ( _pReplaceToken2
)
2085 sErrorMessage
= sErrorMessage
.replaceAt( sErrorMessage
.indexOf( ::rtl::OUString::createFromAscii( "#2" ) ), 2, *_pReplaceToken2
);
2088 impl_appendError( SQLException(
2089 sErrorMessage
, NULL
, getStandardSQLState( SQL_GENERAL_ERROR
), 1000, Any() ) );
2092 // -----------------------------------------------------------------------------
2093 void OSQLParseTreeIterator::impl_appendError( const SQLException
& _rError
)
2095 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger
, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_appendError" );
2096 if ( m_aErrors
.Message
.getLength() )
2098 SQLException
* pErrorChain
= &m_aErrors
;
2099 while ( pErrorChain
->NextException
.hasValue() )
2100 pErrorChain
= static_cast< SQLException
* >( pErrorChain
->NextException
.pData
);
2101 pErrorChain
->NextException
<<= _rError
;
2104 m_aErrors
= _rError
;
2106 // -----------------------------------------------------------------------------