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]
