Tag: cws_src680_qiq User: fs Date: 06/05/16 13:09:23 Modified: /dba/connectivity/source/parse/ sqliterator.cxx
Log: #i51143# minor refactoring File Changes: Directory: /dba/connectivity/source/parse/ ========================================== File [changed]: sqliterator.cxx Url: http://dba.openoffice.org/source/browse/dba/connectivity/source/parse/sqliterator.cxx?r1=1.46.78.2&r2=1.46.78.3 Delta lines: +240 -161 ----------------------- --- sqliterator.cxx 15 May 2006 13:45:33 -0000 1.46.78.2 +++ sqliterator.cxx 16 May 2006 20:09:21 -0000 1.46.78.3 @@ -4,9 +4,9 @@ * * $RCSfile: sqliterator.cxx,v $ * - * $Revision: 1.46.78.2 $ + * $Revision: 1.46.78.3 $ * - * last change: $Author: fs $ $Date: 2006/05/15 13:45:33 $ + * last change: $Author: fs $ $Date: 2006/05/16 20:09:21 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -67,12 +67,18 @@ #ifndef _CONNECTIVITY_DBTOOLS_HXX_ #include "connectivity/dbtools.hxx" #endif +#ifndef TOOLS_DIAGNOSE_EX_H +#include <tools/diagnose_ex.h> +#endif #ifndef CONNECTIVITY_CONNECTION_HXX #include "TConnection.hxx" #endif #ifndef _COMPHELPER_TYPES_HXX_ #include <comphelper/types.hxx> #endif +#ifndef CONNECTIVITY_INC_CONNECTIVITY_DBMETADATA_HXX +#include <connectivity/dbmetadata.hxx> +#endif #ifndef _COM_SUN_STAR_SDB_SQLFILTEROPERATOR_HPP_ #include <com/sun/star/sdb/SQLFilterOperator.hpp> #endif @@ -95,6 +101,7 @@ { struct OSQLParseTreeIteratorImpl { + Reference< XConnection > m_xConnection; Reference< XDatabaseMetaData > m_xDatabaseMetaData; Reference< XNameAccess > m_xTableContainer; Reference< XNameAccess > m_xQueryContainer; @@ -105,9 +112,10 @@ bool m_bIsCaseSensitive; OSQLParseTreeIteratorImpl( const Reference< XConnection >& _rxConnection, const Reference< XNameAccess >& _rxTables ) + :m_xConnection( _rxConnection ) { - OSL_PRECOND( _rxConnection.is(), "OSQLParseTreeIteratorImpl::OSQLParseTreeIteratorImpl: invalid connection!" ); - m_xDatabaseMetaData = _rxConnection->getMetaData(); + OSL_PRECOND( m_xConnection.is(), "OSQLParseTreeIteratorImpl::OSQLParseTreeIteratorImpl: invalid connection!" ); + m_xDatabaseMetaData = m_xConnection->getMetaData(); m_bIsCaseSensitive = m_xDatabaseMetaData.is() && m_xDatabaseMetaData->storesMixedCaseQuotedIdentifiers(); m_pTables.reset( new OSQLTables( m_bIsCaseSensitive ) ); @@ -115,22 +123,12 @@ m_xTableContainer = _rxTables; - bool bSupportsSubQueries = m_xDatabaseMetaData.is() - && ( m_xDatabaseMetaData->supportsSubqueriesInComparisons() - || m_xDatabaseMetaData->supportsSubqueriesInExists() - || m_xDatabaseMetaData->supportsSubqueriesInIns() - || m_xDatabaseMetaData->supportsSubqueriesInQuantifieds() - || m_xDatabaseMetaData->supportsCorrelatedSubqueries() - || m_xDatabaseMetaData->getMaxTablesInSelect() > 1 - ); - // TODO: is there a better way to determine this? The above is not really true. More precise, - // it's a very generous heuristics ... - - if ( bSupportsSubQueries ) + DatabaseMetaData aMetaData( m_xConnection ); + if ( aMetaData.supportsSubqueriesInFrom() ) { // connections might support the XQueriesSupplier interface, if they implement the css.sdb.Connection // service - Reference< XQueriesSupplier > xSuppQueries( _rxConnection, UNO_QUERY ); + Reference< XQueriesSupplier > xSuppQueries( m_xConnection, UNO_QUERY ); if ( xSuppQueries.is() ) m_xQueryContainer = xSuppQueries->getQueries(); } @@ -142,10 +140,10 @@ //----------------------------------------------------------------------------- OSQLParseTreeIterator::OSQLParseTreeIterator(const Reference< XConnection >& _rxConnection, const Reference< XNameAccess >& _rxTables, - const OSQLParseNode* pRoot, - const OSQLParser* _pParser ) + const OSQLParser& _rParser, + const OSQLParseNode* pRoot ) :m_pImpl( new OSQLParseTreeIteratorImpl( _rxConnection, _rxTables ) ) - ,m_pParser( _pParser ) + ,m_rParser( _rParser ) { setParseTree(pRoot); } @@ -176,7 +174,6 @@ m_aParameters = NULL; m_pImpl->m_xTableContainer = NULL; m_pImpl->m_xDatabaseMetaData = NULL; - m_pParser = NULL; m_aCreateColumns = NULL; m_pImpl->m_pTables->clear(); m_pImpl->m_pSubTables->clear(); @@ -305,6 +302,47 @@ } //----------------------------------------------------------------------------- +namespace +{ + ::vos::ORef< OSQLColumns > lcl_getQueryParameterColumns( const OSQLParseTreeIteratorImpl& _rIteratorImpl, const OSQLTable& _rQuery, const OSQLParser& _rParser ) + { + ::vos::ORef< OSQLColumns > pSubQueryParameterColumns( new OSQLColumns() ); + + ::rtl::OUString sSubQueryCommand; + sal_Bool bEscapeProcessing = sal_False; + try + { + Reference< XPropertySet > xQueryProperties( _rQuery, UNO_QUERY_THROW ); + OSL_VERIFY( xQueryProperties->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_COMMAND ) ) >>= sSubQueryCommand ); + OSL_VERIFY( xQueryProperties->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING ) ) >>= bEscapeProcessing ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + do { + + if ( !bEscapeProcessing || ( sSubQueryCommand.getLength() == 0 ) ) + break; + + ::rtl::OUString sError; + ::std::auto_ptr< OSQLParseNode > pSubQueryNode( const_cast< OSQLParser& >( _rParser ).parseTree( sError, sSubQueryCommand, sal_False ) ); + if ( !pSubQueryNode.get() ) + break; + + OSQLParseTreeIterator aSubQueryIterator( _rIteratorImpl.m_xConnection, _rIteratorImpl.m_xTableContainer, _rParser, pSubQueryNode.get() ); + aSubQueryIterator.traverseAll(); + pSubQueryParameterColumns = aSubQueryIterator.getParameters(); + aSubQueryIterator.dispose(); + + } while ( false ); + + return pSubQueryParameterColumns; + } +} + +//----------------------------------------------------------------------------- OSQLTable OSQLParseTreeIterator::impl_locateRecordSource( const ::rtl::OUString& _rComposedName, const ::rtl::OUString& _rAlias ) { if ( !_rComposedName.getLength() ) @@ -345,7 +383,17 @@ // queries win over tables, so if there's a query with this name, take this, no matter if // there's a table, too if ( bQueryDoesExist ) + { 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() ) ); + } else if ( bTableDoesExist ) m_pImpl->m_xTableContainer->getByName( sComposedName ) >>= aReturn; else @@ -570,41 +618,83 @@ sColumnAlias = _pDerivedColumn->getChild(1)->getTokenValue(); return sColumnAlias; } -// ----------------------------------------------------------------------------- -void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode* _pColumnRef, - ::rtl::OUString &_rColumnName, - ::rtl::OUString& _rTableRange) const -{ - getColumnRange( _pColumnRef, m_pImpl->m_xDatabaseMetaData, _rColumnName, _rTableRange ); -} -//----------------------------------------------------------------------------- -void OSQLParseTreeIterator::getColumnRange(const OSQLParseNode* pColumnRef, - const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData>& _xMetaData, - ::rtl::OUString &rColumnName, - ::rtl::OUString &rTableRange) +// ----------------------------------------------------------------------------- +namespace { - - rColumnName = ::rtl::OUString(); - rTableRange = ::rtl::OUString(); - if(SQL_ISRULE(pColumnRef,column_ref))// ab hier ist es sicher eine Columnref + void lcl_getColumnRange( const OSQLParseNode* _pColumnRef, const Reference< XDatabaseMetaData>& _xMetaData, + ::rtl::OUString& _out_rColumnName, ::rtl::OUString& _out_rTableRange, + const OSQLColumns* _pSelectColumns, ::rtl::OUString& _out_rColumnAliasIfPresent ) + { + _out_rColumnName = _out_rTableRange = _out_rColumnAliasIfPresent = ::rtl::OUString(); + if ( SQL_ISRULE( _pColumnRef, column_ref ) ) { - if(pColumnRef->count() > 1) + if( _pColumnRef->count() > 1 ) { - for(sal_Int32 i=0;i<((sal_Int32)pColumnRef->count())-2;i++) // mu"s signed sein, falls count == 1 - pColumnRef->getChild(i)->parseNodeToStr(rTableRange,_xMetaData,NULL,sal_False,sal_False); - // Spaltenname - rColumnName = pColumnRef->getChild(pColumnRef->count()-1)->getChild(0)->getTokenValue(); + for ( sal_Int32 i=0; i<((sal_Int32)_pColumnRef->count())-2; ++i ) + _pColumnRef->getChild(i)->parseNodeToStr( _out_rTableRange, _xMetaData, NULL, sal_False, sal_False ); + _out_rColumnName = _pColumnRef->getChild( _pColumnRef->count()-1 )->getChild(0)->getTokenValue(); } else - rColumnName = pColumnRef->getChild(0)->getTokenValue(); + _out_rColumnName = _pColumnRef->getChild(0)->getTokenValue(); + + // look up the column in the select column, to find an possible alias + if ( _pSelectColumns ) + { + for ( OSQLColumns::const_iterator lookupColumn = _pSelectColumns->begin(); + lookupColumn != _pSelectColumns->end(); + ++lookupColumn + ) + { + Reference< XPropertySet > xColumn( *lookupColumn ); + try + { + ::rtl::OUString sName, sTableName; + xColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_REALNAME ) ) >>= sName; + xColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_TABLENAME ) ) >>= sTableName; + if ( sName == _out_rColumnName && sTableName == _out_rTableRange ) + xColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_NAME ) ) >>= _out_rColumnAliasIfPresent; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); } - else if(SQL_ISRULE(pColumnRef,general_set_fct) || SQL_ISRULE(pColumnRef,set_fct_spec)) + } + } + } + else if(SQL_ISRULE(_pColumnRef,general_set_fct) || SQL_ISRULE(_pColumnRef,set_fct_spec)) { // Funktion - pColumnRef->parseNodeToStr(rColumnName,_xMetaData); + _pColumnRef->parseNodeToStr(_out_rColumnName,_xMetaData); } - else if(pColumnRef->getNodeType() == SQL_NODE_NAME) - rColumnName = pColumnRef->getTokenValue(); + else if(_pColumnRef->getNodeType() == SQL_NODE_NAME) + _out_rColumnName = _pColumnRef->getTokenValue(); + } +} + +// ----------------------------------------------------------------------------- +void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode* _pColumnRef, + ::rtl::OUString& _rColumnName, + ::rtl::OUString& _rTableRange) const +{ + ::rtl::OUString sDummy; + lcl_getColumnRange( _pColumnRef, m_pImpl->m_xDatabaseMetaData, _rColumnName, _rTableRange, NULL, sDummy ); +} + +// ----------------------------------------------------------------------------- +void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode* _pColumnRef, + ::rtl::OUString& _rColumnName, + ::rtl::OUString& _rTableRange, + ::rtl::OUString& _out_rColumnAliasIfPresent ) const +{ + lcl_getColumnRange( _pColumnRef, m_pImpl->m_xDatabaseMetaData, _rColumnName, _rTableRange, &*m_aSelectColumns, _out_rColumnAliasIfPresent ); +} + +//----------------------------------------------------------------------------- +void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode* _pColumnRef, + const Reference< XDatabaseMetaData>& _xMetaData, ::rtl::OUString& _out_rColumnName, ::rtl::OUString& _out_rTableRange ) +{ + ::rtl::OUString sDummy; + lcl_getColumnRange( _pColumnRef, _xMetaData, _out_rColumnName, _out_rTableRange, NULL, sDummy ); } //----------------------------------------------------------------------------- @@ -798,7 +888,7 @@ ::rtl::OUString sTableRange; // check if the column is also a parameter traverseORCriteria(pColumnRef); // num_value_exp - traverseParameter(pColumnRef,NULL,sColumnName,sTableRange); + traverseParameter( pColumnRef, NULL, sColumnName, sTableRange, aColumnAlias ); // gehoeren alle beteiligten Spalten der Funktion zu einer Tabelle if (m_pImpl->m_pTables->size() == 1) @@ -825,7 +915,7 @@ else pColumnRef->getChild(0)->parseNodeToStr( sFunctionName, m_pImpl->m_xDatabaseMetaData, NULL, sal_False, sal_False ); - nType = ::connectivity::OSQLParser::getFunctionReturnType(sFunctionName,m_pParser ? &m_pParser->getContext() : NULL); + nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() ); } } } @@ -1218,45 +1308,44 @@ void OSQLParseTreeIterator::traverseParameter(OSQLParseNode* _pParseNode ,OSQLParseNode* _pColumnRef ,const ::rtl::OUString& _aColumnName - ,const ::rtl::OUString& _aTableRange) + ,const ::rtl::OUString& _aTableRange + ,const ::rtl::OUString& _rColumnAlias) { - if (SQL_ISRULE(_pParseNode,parameter)) - { + if ( !SQL_ISRULE( _pParseNode, parameter ) ) + return; OSL_ENSURE(_pParseNode->count() > 0,"OSQLParseTreeIterator: Fehler im Parse Tree"); OSQLParseNode * pMark = _pParseNode->getChild(0); - ::rtl::OUString aName,rValue; + ::rtl::OUString sParameterName; - ::rtl::OUString aParameterName; if (SQL_ISPUNCTUATION(pMark,"?")) { - // Name = "?", da kein Parametername verfuegbar (z. B. bei Native SQL) - rValue = ::rtl::OUString::createFromAscii("?"); - if(_aColumnName.getLength()) - rValue = _aColumnName; - aName = ::rtl::OUString::createFromAscii("?"); + sParameterName = _rColumnAlias.getLength() + ? _rColumnAlias + : _aColumnName.getLength() + ? _aColumnName + : ::rtl::OUString::createFromAscii("?"); } else if (SQL_ISPUNCTUATION(pMark,":")) { - rValue = _pParseNode->getChild(1)->getTokenValue(); - aName = ::rtl::OUString::createFromAscii(":"); + sParameterName = _pParseNode->getChild(1)->getTokenValue(); } else if (SQL_ISPUNCTUATION(pMark,"[")) { - rValue = _pParseNode->getChild(1)->getTokenValue(); - aName = ::rtl::OUString::createFromAscii("["); + sParameterName = _pParseNode->getChild(1)->getTokenValue(); } else { OSL_ASSERT("OSQLParseTreeIterator: Fehler im Parse Tree"); } + // found a parameter if ( _pColumnRef && (SQL_ISRULE(_pColumnRef,general_set_fct) || SQL_ISRULE(_pColumnRef,set_fct_spec)) ) {// found a function as column_ref ::rtl::OUString sFunctionName; _pColumnRef->getChild(0)->parseNodeToStr( sFunctionName, m_pImpl->m_xDatabaseMetaData, NULL, sal_False, sal_False ); - sal_Int32 nType = ::connectivity::OSQLParser::getFunctionReturnType(sFunctionName,m_pParser ? &m_pParser->getContext() : NULL); + sal_Int32 nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() ); - OParseColumn* pColumn = new OParseColumn( rValue , + OParseColumn* pColumn = new OParseColumn( sParameterName, ::rtl::OUString(), ::rtl::OUString(), ColumnValue::NULLABLE_UNKNOWN, @@ -1282,7 +1371,7 @@ if(aIter != m_aSelectColumns->end()) { OParseColumn* pNewColumn = new OParseColumn(*aIter,isCaseSensitive()); - pNewColumn->setName(rValue); + pNewColumn->setName(sParameterName); pNewColumn->setRealName(_aColumnName); m_aParameters->push_back(pNewColumn); bNotFound = sal_False; @@ -1295,7 +1384,7 @@ if ( xColumn.is() ) { OParseColumn* pNewColumn = new OParseColumn(xColumn,isCaseSensitive()); - pNewColumn->setName(rValue); + pNewColumn->setName(sParameterName); pNewColumn->setRealName(_aColumnName); m_aParameters->push_back(pNewColumn); bNotFound = sal_False; @@ -1303,7 +1392,7 @@ } if ( bNotFound ) { - ::rtl::OUString aNewColName(getUniqueColumnName(rValue)); + ::rtl::OUString aNewColName( getUniqueColumnName( sParameterName ) ); OParseColumn* pColumn = new OParseColumn(aNewColName, ::rtl::OUString(), @@ -1315,12 +1404,11 @@ sal_False, sal_False, isCaseSensitive() ); - pColumn->setName(rValue); - pColumn->setRealName(rValue); + pColumn->setName(aNewColName); + pColumn->setRealName(sParameterName); m_aParameters->push_back(pColumn); } } - } } //----------------------------------------------------------------------------- void OSQLParseTreeIterator::traverseOnePredicate( @@ -1330,18 +1418,17 @@ sal_Bool bCompareNull, OSQLParseNode * pParseNode) { - + if ( !pParseNode ) + return; // Column-Name (und TableRange): - ::rtl::OUString aColumnName; - ::rtl::OUString aTableRange; - getColumnRange(pColumnRef,aColumnName,aTableRange); + ::rtl::OUString aColumnName, aTableRange, sColumnAlias; + getColumnRange( pColumnRef, aColumnName, aTableRange, sColumnAlias); ::rtl::OUString aName; - if (pParseNode) //event. Parameter, oder Columnref oder - { + if (SQL_ISRULE(pParseNode,parameter)) - traverseParameter(pParseNode,pColumnRef,aColumnName,aTableRange); + traverseParameter( pParseNode, pColumnRef, aColumnName, aTableRange, sColumnAlias ); else if (SQL_ISRULE(pParseNode,column_ref))// Column-Name (und TableRange): getColumnRange(pParseNode,aName,rValue); else @@ -1349,9 +1436,6 @@ traverseORCriteria(pParseNode); // if (! aIteratorStatus.IsSuccessful()) return; } - } - - // Fehler einfach weiterreichen ... } //----------------------------------------------------------------------------- @@ -1835,12 +1919,7 @@ // ----------------------------------------------------------------------------- void OSQLParseTreeIterator::impl_appendError( IParseContext::ErrorCode _eError, const ::rtl::OUString* _pReplaceToken1, const ::rtl::OUString* _pReplaceToken2 ) { - OSL_ENSURE( m_pParser, "OSQLParseTreeIterator::impl_appendError: no parser!" ); - // Is this really a valid scenario? Calling this method without a parser? - if ( !m_pParser ) - return; - - ::rtl::OUString sErrorMessage = m_pParser->getContext().getErrorMessage( _eError ); + ::rtl::OUString sErrorMessage = m_rParser.getContext().getErrorMessage( _eError ); if ( _pReplaceToken1 ) { sErrorMessage = sErrorMessage.replaceAt( sErrorMessage.indexOf('#'), 1, *_pReplaceToken1 ); --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
