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

Generated by: LCOV version 1.10