LCOV - code coverage report
Current view: top level - connectivity/source/parse - sqliterator.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 531 973 54.6 %
Date: 2012-08-25 Functions: 49 64 76.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 690 2300 30.0 %

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

Generated by: LCOV version 1.10