Tag: cws_src680_qiq
User: fs      
Date: 2006/06/30 06:06:28

Modified:
   dba/connectivity/source/parse/sqlnode.cxx
   dba/connectivity/source/parse/sqliterator.cxx

Log:
 #i51143# protect against cyclic references in the query names

File Changes:

Directory: /dba/connectivity/source/parse/
==========================================

File [changed]: sqlnode.cxx
Url: 
http://dba.openoffice.org/source/browse/dba/connectivity/source/parse/sqlnode.cxx?r1=1.38.62.10&r2=1.38.62.11
Delta lines:  +95 -46
---------------------
--- sqlnode.cxx 28 Jun 2006 08:40:41 -0000      1.38.62.10
+++ sqlnode.cxx 30 Jun 2006 13:06:25 -0000      1.38.62.11
@@ -4,9 +4,9 @@
  *
  *  $RCSfile: sqlnode.cxx,v $
  *
- *  $Revision: 1.38.62.10 $
+ *  $Revision: 1.38.62.11 $
  *
- *  last change: $Author: fs $ $Date: 2006/06/28 08:40:41 $
+ *  last change: $Author: fs $ $Date: 2006/06/30 13:06:25 $
  *
  *  The Contents of this file are made available subject to
  *  the terms of GNU Lesser General Public License Version 2.1.
@@ -119,6 +119,9 @@
 #ifndef _COMPHELPER_NUMBERS_HXX_
 #include <comphelper/numbers.hxx>
 #endif
+#ifndef _COMPHELPER_STLTYPES_HXX_
+#include <comphelper/stl_types.hxx>
+#endif
 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
 #include "connectivity/dbtools.hxx"
 #endif
@@ -208,14 +211,16 @@
 //=============================================================================
 //= SQLParseNodeParameter
 //=============================================================================
+//-----------------------------------------------------------------------------
 SQLParseNodeParameter::SQLParseNodeParameter( const ::rtl::OUString& 
_rIdentifierQuote, const ::rtl::OUString& _rCatalogSep,
                const Reference< XNumberFormatter >& _xFormatter, const 
Reference< XPropertySet >& _xField,
                const Locale& _rLocale, const IParseContext* _pContext,
-               bool _bIntl, bool _bQuote, sal_Char _cDecSep, bool _bPredicate, 
bool _bParseToSDBC )
+        bool _bIntl, bool _bQuote, sal_Char _cDecSep, bool _bPredicate, bool 
_bParseToSDBC, bool _bCaseSensistiveIdentCompare  )
     :rLocale(_rLocale)
     ,aIdentifierQuote(_rIdentifierQuote)
        ,aCatalogSeparator(_rCatalogSep)
     ,pParser( NULL )
+    ,pSubQueryHistory( new QueryNameSet )
     ,xFormatter(_xFormatter)
     ,xField(_xField)
     ,m_rContext( _pContext ? (const IParseContext&)(*_pContext) : (const 
IParseContext&)OSQLParser::s_aDefaultContext )
@@ -224,6 +229,12 @@
        ,bInternational(_bIntl)
        ,bPredicate(_bPredicate)
     ,bParseToSDBCLevel( _bParseToSDBC )
+    ,bCaseSensistiveIdentCompare( _bCaseSensistiveIdentCompare )
+{
+}
+
+//-----------------------------------------------------------------------------
+SQLParseNodeParameter::~SQLParseNodeParameter()
 {
 }
 
@@ -333,19 +344,35 @@
                ::rtl::OUString 
aIdentifierQuote(xMeta->getIdentifierQuoteString());
                ::rtl::OUString aCatalogSeparator(xMeta->getCatalogSeparator());
 
-               OSQLParseNode::parseNodeToStr( rString,
+        try
+        {
+                   OSQLParseNode::impl_parseNodeToString_throw( rString,
                        SQLParseNodeParameter(
-                aIdentifierQuote, aCatalogSeparator, xFormatter, _xField, 
rIntl, pContext, _bIntl, _bQuote, _cDecSep, _bPredicate, _bSubstitute ) );
+                    aIdentifierQuote, aCatalogSeparator, xFormatter, _xField, 
rIntl, pContext,
+                    _bIntl, _bQuote, _cDecSep, _bPredicate, _bSubstitute,
+                    xMeta->storesMixedCaseQuotedIdentifiers()
+                ) );
+        }
+        catch( const SQLException& )
+        {
+            OSL_ENSURE( false, "OSQLParseNode::parseNodeToStr: this should not 
throw!" );
+            // our callers don't expect this method to throw anything. The 
only known situation
+            // where impl_parseNodeToString_throw can throw is when there is a 
cyclic reference
+            // in the sub queries, but this cannot be the case here, as we do 
not parse to
+            // SDBC level.
+        }
        }
 }
 //-----------------------------------------------------------------------------
-void OSQLParseNode::parseNodeToExecutableStatement( ::rtl::OUString& 
_out_rString, const Reference< XConnection >& _rxConnection, OSQLParser& 
_rParser ) const
+bool OSQLParseNode::parseNodeToExecutableStatement( ::rtl::OUString& 
_out_rString, const Reference< XConnection >& _rxConnection,
+    OSQLParser& _rParser, ::com::sun::star::sdbc::SQLException* _pErrorHolder 
) const
 {
     OSL_PRECOND( _rxConnection.is(), 
"OSQLParseNode::parseNodeToExecutableStatement: invalid connection!" );
     Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData() );
 
     SQLParseNodeParameter aParseParam( xMeta->getIdentifierQuoteString(), 
xMeta->getCatalogSeparator(),
-        NULL, NULL, OParseContext::getDefaultLocale(), NULL, false, true, '.', 
false, true );
+        NULL, NULL, OParseContext::getDefaultLocale(), NULL, false, true, '.', 
false, true,
+        xMeta->storesMixedCaseQuotedIdentifiers() );
 
     DatabaseMetaData aMeta( _rxConnection );
     if ( aMeta.supportsSubqueriesInFrom() )
@@ -359,7 +386,18 @@
     aParseParam.pParser = &_rParser;
 
     _out_rString = ::rtl::OUString();
-    parseNodeToStr( _out_rString, aParseParam );
+    bool bSuccess = false;
+    try
+    {
+        impl_parseNodeToString_throw( _out_rString, aParseParam );
+        bSuccess = true;
+    }
+    catch( const SQLException& e )
+    {
+        if ( _pErrorHolder )
+            *_pErrorHolder = e;
+    }
+    return bSuccess;
 }
 
 //-----------------------------------------------------------------------------
@@ -412,7 +450,7 @@
 }
 
 //-----------------------------------------------------------------------------
-void OSQLParseNode::parseNodeToStr(::rtl::OUString& rString, const 
SQLParseNodeParameter& rParam) const
+void OSQLParseNode::impl_parseNodeToString_throw(::rtl::OUString& rString, 
const SQLParseNodeParameter& rParam) const
 {
     if ( isToken() )
     {
@@ -432,15 +470,15 @@
                if(rString.getLength())
                        rString += ::rtl::OUString::createFromAscii(" ");
                if (nCount == 1)        // ?
-                       m_aChilds[0]->parseNodeToStr(rString, rParam);
+                       m_aChilds[0]->impl_parseNodeToString_throw( rString, 
rParam );
                else if (nCount == 2)   // :Name
                {
-                       m_aChilds[0]->parseNodeToStr(rString, rParam);
+                       m_aChilds[0]->impl_parseNodeToString_throw( rString, 
rParam );
                        rString += m_aChilds[1]->m_aNodeValue;
                }                                   // [Name]
                else
                {
-                       m_aChilds[0]->parseNodeToStr(rString, rParam);
+                       m_aChilds[0]->impl_parseNodeToString_throw( rString, 
rParam );
                        rString += m_aChilds[1]->m_aNodeValue;
                        rString += m_aChilds[2]->m_aNodeValue;
                }
@@ -454,14 +492,14 @@
             ||  ( ( nCount == 6 ) &&  SQL_ISPUNCTUATION( m_aChilds[0], "(" ) )
             )
         {
-                   tableRangeNodeToStr(rString, rParam);
+                   impl_parseTableRangeNodeToString_throw( rString, rParam );
             bHandled = true;
         }
         break;
 
     // table name - might be a query name
     case table_name:
-        bHandled = tableNameNodeToStr( rString, rParam );
+        bHandled = impl_parseTableNameNodeToString_throw( rString, rParam );
         break;
 
     case as:
@@ -473,7 +511,7 @@
            // je nachdem ob international angegeben wird oder nicht wird like 
anders behandelt
            // interanational: *, ? sind Platzhalter
            // sonst SQL92 konform: %, _
-               likeNodeToStr(rString, rParam);
+               impl_parseLikeNodeToString_throw( rString, rParam );
         bHandled = true;
         break;
 
@@ -490,7 +528,7 @@
                        SQLParseNodeParameter aNewParam(rParam);
                        aNewParam.bQuote = ( SQL_ISRULE(this,length_exp)        
|| SQL_ISRULE(this,char_value_fct) );
 
-                       m_aChilds[0]->parseNodeToStr(rString, aNewParam);
+                       m_aChilds[0]->impl_parseNodeToString_throw( rString, 
aNewParam );
                        aNewParam.bQuote = rParam.bQuote;
                        aNewParam.bPredicate = sal_False; // disable [ ] around 
names
                        ::rtl::OUString aStringPara;
@@ -499,7 +537,7 @@
                                const OSQLParseNode * pSubTree = m_aChilds[i];
                                if (pSubTree)
                                {
-                                       pSubTree->parseNodeToStr(aStringPara, 
aNewParam);
+                                       pSubTree->impl_parseNodeToString_throw( 
aStringPara, aNewParam );
 
                                        // bei den CommaListen zwischen alle 
Subtrees Commas setzen
                                        if ((m_eNodeType == 
SQL_NODE_COMMALISTRULE)     && (i < (nCount - 1)))
@@ -577,7 +615,7 @@
                                }
                                else
                                {
-                                       pSubTree->parseNodeToStr(rString, 
aNewParam);
+                                       pSubTree->impl_parseNodeToString_throw( 
rString, aNewParam );
                                        i++;
 
                                        // bei den CommaListen zwischen alle 
Subtrees Commas setzen
@@ -587,7 +625,7 @@
                        }
                        else
                        {
-                               pSubTree->parseNodeToStr(rString, aNewParam);
+                               pSubTree->impl_parseNodeToString_throw( 
rString, aNewParam );
                                i++;
 
                                // bei den CommaListen zwischen alle Subtrees 
Commas setzen
@@ -604,10 +642,10 @@
 }
 
 //-----------------------------------------------------------------------------
-bool OSQLParseNode::tableNameNodeToStr( ::rtl::OUString& rString, const 
SQLParseNodeParameter& rParam ) const
+bool OSQLParseNode::impl_parseTableNameNodeToString_throw( ::rtl::OUString& 
rString, const SQLParseNodeParameter& rParam ) const
 {
     // is the table_name part of a table_ref?
-    OSL_ENSURE( getParent(), "OSQLParseNode::tableNameNodeToStr: table_name 
without parent?" );
+    OSL_ENSURE( getParent(), 
"OSQLParseNode::impl_parseTableNameNodeToString_throw: table_name without 
parent?" );
     if ( !getParent() || ( getParent()->getKnownRuleID() != table_ref ) )
         return false;
 
@@ -626,6 +664,11 @@
         if ( !bIsQuery )
             return false;
 
+        // avoid recursion (e.g. "foo" defined as "SELECT * FROM bar" and 
"bar" defined as "SELECT * FROM foo".
+        if ( rParam.pSubQueryHistory->find( sTableOrQueryName ) != 
rParam.pSubQueryHistory->end() )
+            ::dbtools::throwSQLException( "cyclic sub queries", 
SQL_CYCLIC_SUB_QUERIES, NULL );
+        rParam.pSubQueryHistory->insert( sTableOrQueryName );
+
         Reference< XPropertySet > xQuery( rParam.xQueries->getByName( 
sTableOrQueryName ), UNO_QUERY_THROW );
 
         // substitute the query name with the constituting command
@@ -636,7 +679,7 @@
         OSL_VERIFY( xQuery->getPropertyValue( 
OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING ) ) 
>>= bEscapeProcessing );
 
         // the query we found here might itself be based on another query, so 
parse it recursively
-        OSL_ENSURE( rParam.pParser, "OSQLParseNode::tableNameNodeToStr: cannot 
analyze sub queries without a parser!" );
+        OSL_ENSURE( rParam.pParser, 
"OSQLParseNode::impl_parseTableNameNodeToString_throw: cannot analyze sub 
queries without a parser!" );
         if ( bEscapeProcessing && rParam.pParser )
         {
             ::rtl::OUString sError;
@@ -645,7 +688,7 @@
             {
                 // parse the sub-select to SDBC level, too
                 ::rtl::OUString sSubSelect;
-                pSubQueryNode->parseNodeToStr( sSubSelect, rParam );
+                pSubQueryNode->impl_parseNodeToString_throw( sSubSelect, 
rParam );
                 if ( sSubSelect.getLength() )
                     sCommand = sSubSelect;
             }
@@ -666,6 +709,10 @@
 
         return true;
     }
+    catch( const SQLException& )
+    {
+        throw;
+    }
     catch( const Exception& )
     {
         DBG_UNHANDLED_EXCEPTION();
@@ -674,33 +721,31 @@
 }
 
 //-----------------------------------------------------------------------------
-void OSQLParseNode::tableRangeNodeToStr(::rtl::OUString& rString, const 
SQLParseNodeParameter& rParam) const
+void OSQLParseNode::impl_parseTableRangeNodeToString_throw(::rtl::OUString& 
rString, const SQLParseNodeParameter& rParam) const
 {
        sal_uInt32 nCount(count());
        rString += ::rtl::OUString::createFromAscii(" ");
 
-       SQLParseNodeParameter aNewParam(rParam);
-       //      aNewParam.bQuote = sal_False;
        if (nCount == 4)
        {
-               m_aChilds[0]->parseNodeToStr(rString, rParam);
-               m_aChilds[1]->parseNodeToStr(rString, rParam);
-               m_aChilds[2]->parseNodeToStr(rString, aNewParam);
-               m_aChilds[3]->parseNodeToStr(rString, rParam);
+               m_aChilds[0]->impl_parseNodeToString_throw( rString, rParam );
+               m_aChilds[1]->impl_parseNodeToString_throw( rString, rParam );
+               m_aChilds[2]->impl_parseNodeToString_throw( rString, rParam );
+               m_aChilds[3]->impl_parseNodeToString_throw( rString, rParam );
        }
        else if(nCount == 6 && SQL_ISPUNCTUATION(m_aChilds[0],"("))
        {
-               m_aChilds[0]->parseNodeToStr(rString, rParam);
-               m_aChilds[1]->parseNodeToStr(rString, rParam);
-               m_aChilds[2]->parseNodeToStr(rString, rParam);
-               m_aChilds[3]->parseNodeToStr(rString, rParam);
-               m_aChilds[4]->parseNodeToStr(rString, aNewParam);
-               m_aChilds[5]->parseNodeToStr(rString, rParam);
+               m_aChilds[0]->impl_parseNodeToString_throw( rString, rParam );
+               m_aChilds[1]->impl_parseNodeToString_throw( rString, rParam );
+               m_aChilds[2]->impl_parseNodeToString_throw( rString, rParam );
+               m_aChilds[3]->impl_parseNodeToString_throw( rString, rParam );
+               m_aChilds[4]->impl_parseNodeToString_throw( rString, rParam );
+               m_aChilds[5]->impl_parseNodeToString_throw( rString, rParam );
        }
 }
 
 //-----------------------------------------------------------------------------
-void OSQLParseNode::likeNodeToStr(::rtl::OUString& rString, const 
SQLParseNodeParameter& rParam) const
+void OSQLParseNode::impl_parseLikeNodeToString_throw( ::rtl::OUString& 
rString, const SQLParseNodeParameter& rParam ) const
 {
        OSL_ENSURE(count() >= 4,"count != 5: Prepare for GPF");
 
@@ -725,7 +770,7 @@
                }
                catch ( Exception& )
                {
-                       OSL_ENSURE(0,"OSQLParseNode::likeNodeToStr Exception 
occured!");
+                       OSL_ENSURE( false, 
"OSQLParseNode::impl_parseLikeNodeToString_throw Exception occured!" );
                }
                if ( !m_aChilds[0]->isLeaf() )
                {
@@ -737,11 +782,11 @@
        }
 
        if (bAddName)
-               m_aChilds[0]->parseNodeToStr(rString, aNewParam);
+               m_aChilds[0]->impl_parseNodeToString_throw( rString, aNewParam 
);
 
-       m_aChilds[1]->parseNodeToStr(rString, aNewParam);
+       m_aChilds[1]->impl_parseNodeToString_throw( rString, aNewParam );
        if(count() == 5)
-               m_aChilds[2]->parseNodeToStr(rString, aNewParam);
+               m_aChilds[2]->impl_parseNodeToString_throw( rString, aNewParam 
);
 
        sal_Int32 nCurentPos = m_aChilds.size()-2;
        pParaNode = m_aChilds[nCurentPos];
@@ -754,9 +799,9 @@
                rString += 
SetQuotation(aStr,::rtl::OUString::createFromAscii("\'"),::rtl::OUString::createFromAscii("\'\'"));
        }
        else
-               pParaNode->parseNodeToStr(rString, aNewParam);
+               pParaNode->impl_parseNodeToString_throw( rString, aNewParam );
 
-       pEscNode->parseNodeToStr(rString, aNewParam);
+       pEscNode->impl_parseNodeToString_throw( rString, aNewParam );
 }
 
 
@@ -854,6 +899,7 @@
                                                        break;
                                                default:
                                                        m_sErrorMessage = 
m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_COMPARE);
+                            break;
                                        }
                                        break;
                                case SQL_NODE_ACCESS_DATE:
@@ -870,6 +916,7 @@
                                                        break;
                                                default:
                                                        m_sErrorMessage = 
m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_COMPARE);
+                            break;
                                        }
                                        break;
                                case SQL_NODE_INTNUM:
@@ -903,6 +950,7 @@
                                                        break;
                                                default:
                                                        m_sErrorMessage = 
m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_INT_COMPARE);
+                            break;
                                        }
                                        break;
                                case SQL_NODE_APPROXNUM:
@@ -935,6 +983,7 @@
                                                case DataType::INTEGER:
                                                default:
                                                        m_sErrorMessage = 
m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_REAL_COMPARE);
+                            break;
                                        }
                                        break;
                 default:
@@ -1011,15 +1060,15 @@
                                                nErg = 1;
                                                break;
                                        default:
-                                       {
                                                m_sErrorMessage = 
m_pContext->getErrorMessage(IParseContext::ERROR_VALUE_NO_LIKE);
                                                m_sErrorMessage = 
m_sErrorMessage.replaceAt(m_sErrorMessage.indexOf(::rtl::OUString::createFromAscii("#1")),2,pLiteral->getTokenValue());
-                                       }
+                        break;
                                }
                        }
                        break;
                default:
                        m_sErrorMessage = 
m_pContext->getErrorMessage(IParseContext::ERROR_FIELD_NO_LIKE);
+            break;
        }
        return nErg;
 }

File [changed]: sqliterator.cxx
Url: 
http://dba.openoffice.org/source/browse/dba/connectivity/source/parse/sqliterator.cxx?r1=1.46.78.11&r2=1.46.78.12
Delta lines:  +166 -95
----------------------
--- sqliterator.cxx     28 Jun 2006 08:40:40 -0000      1.46.78.11
+++ sqliterator.cxx     30 Jun 2006 13:06:25 -0000      1.46.78.12
@@ -4,9 +4,9 @@
  *
  *  $RCSfile: sqliterator.cxx,v $
  *
- *  $Revision: 1.46.78.11 $
+ *  $Revision: 1.46.78.12 $
  *
- *  last change: $Author: fs $ $Date: 2006/06/28 08:40:40 $
+ *  last change: $Author: fs $ $Date: 2006/06/30 13:06:25 $
  *
  *  The Contents of this file are made available subject to
  *  the terms of GNU Lesser General Public License Version 2.1.
@@ -111,11 +111,16 @@
 
         ::std::auto_ptr< OSQLTables >   m_pTables;      /// all tables which 
participate in the SQL statement
         ::std::auto_ptr< OSQLTables >   m_pSubTables;   /// all tables from 
sub queries not the tables from the select tables
+        ::boost::shared_ptr< QueryNameSet > m_pForbiddenQueryNames;
+
+        sal_uInt32                      m_nIncludeMask;
 
         bool                            m_bIsCaseSensitive;
 
         OSQLParseTreeIteratorImpl( const Reference< XConnection >& 
_rxConnection, const Reference< XNameAccess >& _rxTables ) 
             :m_xConnection( _rxConnection )
+            ,m_nIncludeMask( OSQLParseTreeIterator::All )
+            ,m_bIsCaseSensitive( true )
                {
             OSL_PRECOND( m_xConnection.is(), 
"OSQLParseTreeIteratorImpl::OSQLParseTreeIteratorImpl: invalid connection!" );
             m_xDatabaseMetaData = m_xConnection->getMetaData();
@@ -137,7 +142,39 @@
             }
         }
                
-               OSQLParseTreeIteratorImpl(){}
+    public:
+        inline  bool    isQueryAllowed( const ::rtl::OUString& _rQueryName )
+        {
+            if ( !m_pForbiddenQueryNames.get() )
+                return true;
+            if ( m_pForbiddenQueryNames->find( _rQueryName ) == 
m_pForbiddenQueryNames->end() )
+                return true;
+            return false;
+        }
+       };
+
+    //-------------------------------------------------------------------------
+    /** helper class for temporarily adding a query name to a list of 
forbidden query names
+    */
+    class ForbidQueryName
+    {
+        ::boost::shared_ptr< QueryNameSet >&    m_rpAllForbiddenNames;
+        ::rtl::OUString                         m_sForbiddenQueryName;
+
+    public:
+        ForbidQueryName( OSQLParseTreeIteratorImpl& _rIteratorImpl, const 
::rtl::OUString _rForbiddenQueryName )
+            :m_rpAllForbiddenNames( _rIteratorImpl.m_pForbiddenQueryNames )
+            ,m_sForbiddenQueryName( _rForbiddenQueryName )
+        {
+            if ( !m_rpAllForbiddenNames.get() )
+                m_rpAllForbiddenNames.reset( new QueryNameSet );
+            m_rpAllForbiddenNames->insert( m_sForbiddenQueryName );
+        }
+
+        ~ForbidQueryName()
+        {
+            m_rpAllForbiddenNames->insert( m_sForbiddenQueryName );
+        }
        };
 }
 //-----------------------------------------------------------------------------
@@ -150,6 +187,16 @@
 {
        setParseTree(pRoot);
 }
+
+//-----------------------------------------------------------------------------
+OSQLParseTreeIterator::OSQLParseTreeIterator( const OSQLParseTreeIterator& 
_rParentIterator, const OSQLParser& _rParser, const OSQLParseNode* pRoot )
+    :m_pImpl( new OSQLParseTreeIteratorImpl( 
_rParentIterator.m_pImpl->m_xConnection, 
_rParentIterator.m_pImpl->m_xTableContainer ) )
+       ,m_rParser( _rParser )
+{
+    m_pImpl->m_pForbiddenQueryNames = 
_rParentIterator.m_pImpl->m_pForbiddenQueryNames;
+       setParseTree( pRoot );
+}
+
 //-----------------------------------------------------------------------------
 OSQLParseTreeIterator::~OSQLParseTreeIterator()
 {
@@ -300,12 +347,15 @@
 }
 
 //-----------------------------------------------------------------------------
-namespace
+void OSQLParseTreeIterator::impl_getQueryParameterColumns( const OSQLTable& 
_rQuery  )
 {
-    ::vos::ORef< OSQLColumns >  lcl_getQueryParameterColumns( const 
OSQLParseTreeIteratorImpl& _rIteratorImpl, const OSQLTable& _rQuery, const 
OSQLParser& _rParser )
-    {
+    if ( ( m_pImpl->m_nIncludeMask & Parameters ) == 0 )
+        // parameters not to be included in the traversal
+        return;
+
         ::vos::ORef< OSQLColumns > pSubQueryParameterColumns( new 
OSQLColumns() );
 
+    // get the command and the EscapeProcessing properties from the sub query
         ::rtl::OUString sSubQueryCommand;
         sal_Bool bEscapeProcessing = sal_False;
         try
@@ -319,25 +369,27 @@
                DBG_UNHANDLED_EXCEPTION();
         }
 
+    // parse the sub query
         do {
 
         if ( !bEscapeProcessing || ( sSubQueryCommand.getLength() == 0 ) )
             break;
 
         ::rtl::OUString sError;
-        ::std::auto_ptr< OSQLParseNode > pSubQueryNode( const_cast< 
OSQLParser& >( _rParser ).parseTree( sError, sSubQueryCommand, sal_False ) );
+    ::std::auto_ptr< OSQLParseNode > pSubQueryNode( const_cast< OSQLParser& >( 
m_rParser ).parseTree( sError, sSubQueryCommand, sal_False ) );
         if ( !pSubQueryNode.get() )
             break;
 
-        OSQLParseTreeIterator aSubQueryIterator( _rIteratorImpl.m_xConnection, 
_rIteratorImpl.m_xTableContainer, _rParser, pSubQueryNode.get() );
-        aSubQueryIterator.traverseAll();
+    OSQLParseTreeIterator aSubQueryIterator( *this, m_rParser, 
pSubQueryNode.get() );
+    aSubQueryIterator.traverseSome( Parameters );
         pSubQueryParameterColumns = aSubQueryIterator.getParameters();
         aSubQueryIterator.dispose();
 
         } while ( false );
 
-        return pSubQueryParameterColumns;
-    }
+    // copy the parameters of the sub query to our own parameter array
+    ::std::copy( pSubQueryParameterColumns->begin(), 
pSubQueryParameterColumns->end(),
+        ::std::insert_iterator< OSQLColumns >( *m_aParameters, 
m_aParameters->end() ) );
 }
 
 //-----------------------------------------------------------------------------
@@ -384,15 +436,23 @@
             // there's a table, too
             if ( bQueryDoesExist )
             {
+                if  ( !m_pImpl->isQueryAllowed( sComposedName ) )
+                {
+                    impl_appendError( SQLException(
+                        ::rtl::OUString::createFromAscii( "cyclic sub queries" 
),
+                        NULL,
+                        getStandardSQLState( SQL_CYCLIC_SUB_QUERIES ),
+                        0,
+                        Any()
+                    ) );
+                    return NULL;
+                }
+
                 m_pImpl->m_xQueryContainer->getByName( sComposedName ) >>= 
aReturn;
 
-                ::vos::ORef< OSQLColumns > pSubQueryParameterColumns =
-                    lcl_getQueryParameterColumns( *m_pImpl, aReturn, m_rParser 
);
-                OSL_ENSURE( !pSubQueryParameterColumns.isEmpty(), 
"OSQLParseTreeIterator::impl_locateRecordSource: not even an empty colulumns 
collection?" );
-                if ( !pSubQueryParameterColumns.isEmpty() )
-                    // copy the parameters of the sub query to our own 
parameter array
-                    ::std::copy( pSubQueryParameterColumns->begin(), 
pSubQueryParameterColumns->end(),
-                        ::std::insert_iterator< OSQLColumns >( *m_aParameters, 
m_aParameters->end() ) );
+                // collect the parameters from the sub query
+                ForbidQueryName aForbidName( *m_pImpl, sComposedName );
+                impl_getQueryParameterColumns( aReturn );
             }
             else if ( bTableDoesExist )
                 m_pImpl->m_xTableContainer->getByName( sComposedName ) >>= 
aReturn;
@@ -418,6 +478,10 @@
 //-----------------------------------------------------------------------------
 void OSQLParseTreeIterator::traverseOneTableName( OSQLTables& _rTables,const 
OSQLParseNode * pTableName, const ::rtl::OUString & rTableRange )
 {
+    if ( ( m_pImpl->m_nIncludeMask & TableNames ) == 0 )
+        // tables should not be included in the traversal
+        return;
+
        OSL_ENSURE(pTableName != 
NULL,"OSQLParseTreeIterator::traverseOneTableName: pTableName == NULL");
 
        Any aCatalog;
@@ -585,15 +649,10 @@
        }
 }
 //-----------------------------------------------------------------------------
-void OSQLParseTreeIterator::traverseTableNames(OSQLTables& _rTables)
+bool OSQLParseTreeIterator::traverseTableNames(OSQLTables& _rTables)
 {
-       
-       //      aIteratorStatus.Clear();
-
-       if (m_pParseTree == NULL) {
-               //aIteratorStatus.setInvalidStatement();
-               return;
-       }
+       if ( m_pParseTree == NULL )
+               return false;
 
        OSQLParseNode* pTableName = NULL;
 
@@ -621,6 +680,8 @@
         ::rtl::OUString sTableRange;
            traverseOneTableName( _rTables, pTableName, sTableRange );
     }
+
+    return !hasErrors();
 }
 //-----------------------------------------------------------------------------
 ::rtl::OUString OSQLParseTreeIterator::getColumnAlias(const OSQLParseNode* 
_pDerivedColumn)
@@ -828,22 +889,18 @@
        } 
 }
 //-----------------------------------------------------------------------------
-void OSQLParseTreeIterator::traverseSelectColumnNames(const OSQLParseNode* 
pSelectNode)
+bool OSQLParseTreeIterator::traverseSelectColumnNames(const OSQLParseNode* 
pSelectNode)
 {
-       
-       //      aIteratorStatus.Clear();
-
        if (!pSelectNode || m_eStatementType != SQL_STATEMENT_SELECT || 
m_pImpl->m_pTables->empty())
        {
                impl_appendError( IParseContext::ERROR_GENERAL );
-               return;
+               return false;
        }
 
        if(SQL_ISRULE(pSelectNode,union_statement))
        {
-               traverseSelectColumnNames(pSelectNode->getChild(0));
-//             traverseSelectColumnNames(pSelectNode->getChild(3));
-               return;
+               return  traverseSelectColumnNames( pSelectNode->getChild( 0 ) )
+            /*&&  traverseSelectColumnNames( pSelectNode->getChild( 3 ) )*/;
        }
 
        // nyi: mehr Pruefung auf korrekte Struktur!
@@ -946,15 +1003,17 @@
                                
setSelectColumnName(m_aSelectColumns,sColumnName,aColumnAlias,aTableRange,bFkt,nType,SQL_ISRULE(pColumnRef,general_set_fct)
 || SQL_ISRULE(pColumnRef,set_fct_spec));
                        }
                }
-
        } 
+
+    return !hasErrors();
 }
 
 
 //-----------------------------------------------------------------------------
-void OSQLParseTreeIterator::traverseOrderByColumnNames(const OSQLParseNode* 
pSelectNode)
+bool OSQLParseTreeIterator::traverseOrderByColumnNames(const OSQLParseNode* 
pSelectNode)
 {
-       traverseByColumnNames(pSelectNode,sal_True);
+       traverseByColumnNames( pSelectNode, sal_True );
+    return !hasErrors();
 }
 //-----------------------------------------------------------------------------
 void OSQLParseTreeIterator::traverseByColumnNames(const OSQLParseNode* 
pSelectNode,sal_Bool _bOrder)
@@ -1045,21 +1104,16 @@
        }
 }
 //-----------------------------------------------------------------------------
-void OSQLParseTreeIterator::traverseGroupByColumnNames(const OSQLParseNode* 
pSelectNode)
+bool OSQLParseTreeIterator::traverseGroupByColumnNames(const OSQLParseNode* 
pSelectNode)
 {
-       traverseByColumnNames(pSelectNode,sal_False);
+       traverseByColumnNames( pSelectNode, sal_False );
+    return !hasErrors();
 }
 //-----------------------------------------------------------------------------
-void OSQLParseTreeIterator::traverseSelectionCriteria(const OSQLParseNode* 
pSelectNode)
+bool OSQLParseTreeIterator::traverseSelectionCriteria(const OSQLParseNode* 
pSelectNode)
 {
-       
-       //      aIteratorStatus.Clear();
-
-       if (pSelectNode == NULL) 
-       {
-               //aIteratorStatus.setInvalidStatement();
-               return;
-       }
+       if ( pSelectNode == NULL )
+               return false;
 
 
        // Parse Tree analysieren (je nach Statement-Typ)
@@ -1070,9 +1124,8 @@
        {
                if(SQL_ISRULE(pSelectNode,union_statement))
                {
-                       traverseSelectionCriteria(pSelectNode->getChild(0));
-                       traverseSelectionCriteria(pSelectNode->getChild(3));
-                       return;
+                       return  traverseSelectionCriteria( 
pSelectNode->getChild( 0 ) )
+                &&  traverseSelectionCriteria( pSelectNode->getChild( 3 ) );
                }
                OSL_ENSURE(pSelectNode->count() >= 4,"OSQLParseTreeIterator: 
error in parse tree!");
 
@@ -1093,14 +1146,14 @@
                OSL_ASSERT("OSQLParseTreeIterator::getSelectionCriteria: 
positioned nyi");
        } else {
                // Anderes Statement. Keine Selektionskriterien.
-               return;
+               return false;
        }
 
        if (! SQL_ISRULE(pWhereClause,where_clause)) {
                // Die Where Clause ist meistens optional, d. h. es koennte 
sich auch
                // um "optional_where_clause" handeln.
                
OSL_ENSURE(SQL_ISRULE(pWhereClause,opt_where_clause),"OSQLParseTreeIterator: 
error in parse tree!");
-               return;
+               return false;
        }
 
        // Wenn es aber eine where_clause ist, dann darf sie nicht leer sein:
@@ -1109,14 +1162,13 @@
        OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1);
        OSL_ENSURE(pComparisonPredicate != NULL,"OSQLParseTreeIterator: error 
in parse tree!");
 
-
        //
        // Und nun die Vergleichskriterien abarbeiten (rekursiv, alles ist 
erstmal ein OR-Kriterium):
        //
 
        traverseORCriteria(pComparisonPredicate);
-       //      if (! aIteratorStatus.IsSuccessful()) return;
 
+    return !hasErrors();
 }
 
 //-----------------------------------------------------------------------------
@@ -1298,6 +1350,11 @@
 {
        if ( !SQL_ISRULE( _pParseNode, parameter ) )
         return;
+
+    if ( ( m_pImpl->m_nIncludeMask & Parameters ) == 0)
+        // parameters not to be included in the traversal
+        return;
+
        OSL_ENSURE(_pParseNode->count() > 0,"OSQLParseTreeIterator: error in 
parse tree!");
        OSQLParseNode * pMark = _pParseNode->getChild(0);
        ::rtl::OUString sParameterName;
@@ -1422,26 +1479,36 @@
 }
 
 //-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::traverseSome( sal_uInt32 _nIncludeMask )
+{
+    m_pImpl->m_nIncludeMask = _nIncludeMask;
+    impl_traverse();
+}
+
+//-----------------------------------------------------------------------------
 void OSQLParseTreeIterator::traverseAll()
 {
-       traverseTableNames( *m_pImpl->m_pTables );
-       //      if (! aIteratorStatus.IsSuccessful()) return;
+    m_pImpl->m_nIncludeMask = All;
+    impl_traverse();
+}
+
+//-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::impl_traverse()
+{
+       if ( !traverseTableNames( *m_pImpl->m_pTables ) )
+        return;
 
     switch ( m_eStatementType )
     {
     case SQL_STATEMENT_SELECT:
        {
                const OSQLParseNode* pSelectNode = m_pParseTree;
-               traverseSelectColumnNames(pSelectNode);
-//             if (! aIteratorStatus.IsSuccessful())
-//                     return;
-               traverseOrderByColumnNames(pSelectNode);
-               traverseGroupByColumnNames(pSelectNode);
-//             if (! aIteratorStatus.IsSuccessful())
-//                     return;
-               traverseSelectionCriteria(pSelectNode);
-               //      if (! aIteratorStatus.IsSuccessful())
-                       //      return;
+               if  (   !traverseSelectColumnNames( pSelectNode )
+            ||  !traverseOrderByColumnNames( pSelectNode )
+            ||  !traverseGroupByColumnNames( pSelectNode )
+            ||  !traverseSelectionCriteria( pSelectNode )
+            )
+            return;
        }
     break;
     case SQL_STATEMENT_CREATE_TABLE:
@@ -1909,16 +1976,20 @@
                sErrorMessage = sErrorMessage.replaceAt( 
sErrorMessage.indexOf('#'), 1, *_pReplaceToken2 );
     }
 
-    SQLException aAppendError(
-        sErrorMessage, NULL, OMetaConnection::getPropMap().getNameByIndex( 
PROPERTY_ID_HY0000 ), 1000, Any() );
+    impl_appendError( SQLException(
+        sErrorMessage, NULL, getStandardSQLState( SQL_GENERAL_ERROR ), 1000, 
Any() ) );
+}
 
+// 
-----------------------------------------------------------------------------
+void OSQLParseTreeIterator::impl_appendError( const SQLException& _rError )
+{
     if ( m_aErrors.Message.getLength() )
        {
         SQLException* pErrorChain = &m_aErrors;
                while ( pErrorChain->NextException.hasValue() )
             pErrorChain = static_cast< SQLException* >( 
pErrorChain->NextException.pData );
-               pErrorChain->NextException <<= aAppendError;
+               pErrorChain->NextException <<= _rError;
        }
        else
-               m_aErrors = aAppendError;
+               m_aErrors = _rError;
 }




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to