LCOV - code coverage report
Current view: top level - libreoffice/connectivity/source/parse - sqliterator.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 322 983 32.8 %
Date: 2012-12-27 Functions: 33 64 51.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10