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