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]

Reply via email to