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

Generated by: LCOV version 1.10