diff options
Diffstat (limited to 'dbaccess/source/core/api/SingleSelectQueryComposer.cxx')
-rw-r--r-- | dbaccess/source/core/api/SingleSelectQueryComposer.cxx | 139 |
1 files changed, 84 insertions, 55 deletions
diff --git a/dbaccess/source/core/api/SingleSelectQueryComposer.cxx b/dbaccess/source/core/api/SingleSelectQueryComposer.cxx index 4583dd3dfabf..c8a8f9ba01d1 100644 --- a/dbaccess/source/core/api/SingleSelectQueryComposer.cxx +++ b/dbaccess/source/core/api/SingleSelectQueryComposer.cxx @@ -262,7 +262,8 @@ OSingleSelectQueryComposer::~OSingleSelectQueryComposer() delete *aColIter; ::std::vector<OPrivateTables*>::iterator aTabIter = m_aTablesCollection.begin(); - for(;aTabIter != m_aTablesCollection.end();++aTabIter) + ::std::vector<OPrivateTables*>::iterator aTabEnd = m_aTablesCollection.end(); + for(;aTabIter != aTabEnd;++aTabIter) delete *aTabIter; } // ------------------------------------------------------------------------- @@ -343,7 +344,7 @@ void OSingleSelectQueryComposer::setQuery_Impl( const ::rtl::OUString& command ) // update columns and tables // why? Shouldn't this be done on request only? // otherwise nothing is working anymore :-) - getColumns(); +// getColumns(); getTables(); } // ----------------------------------------------------------------------------- @@ -379,6 +380,7 @@ void SAL_CALL OSingleSelectQueryComposer::appendFilterByColumn( const Reference< { ::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed); + getColumns(); if ( !column.is() || !m_aCurrentColumns[SelectColumns] || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME) @@ -572,14 +574,19 @@ void OSingleSelectQueryComposer::setSingleAdditiveClause( SQLPart _ePart, const *pComposer, getKeyword( _ePart ) ); // construct the complete statement - ::rtl::OUString aSql(m_aPureSelectSQL); + ::rtl::OUStringBuffer aSql(m_aPureSelectSQL); for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) - aSql += aClauses[ eLoopParts ]; + aSql.append(aClauses[ eLoopParts ]); // set the query - setQuery_Impl(aSql); - // parameters may also have changed - clearParametersCollection(); + setQuery_Impl(aSql.makeStringAndClear()); + + // clear column collections which (might) have changed + clearColumns( ParameterColumns ); + if ( _ePart == Order ) + clearColumns( OrderColumns ); + if ( _ePart == Group ) + clearColumns( GroupByColumns ); // also, since the "additive filter" change, we need to rebuild our "additive" statement aSql = m_aPureSelectSQL; @@ -590,10 +597,10 @@ void OSingleSelectQueryComposer::setSingleAdditiveClause( SQLPart _ePart, const aClauses[ _ePart ] = getComposedClause( ::rtl::OUString(), _rClause, *pComposer, getKeyword( _ePart ) ); // and parse it, so that m_aAdditiveIterator is up to date for ( SQLPart eLoopParts = Where; eLoopParts != SQLPartCount; incSQLPart( eLoopParts ) ) - aSql += aClauses[ eLoopParts ]; + aSql.append(aClauses[ eLoopParts ]); try { - parseAndCheck_throwError( m_aSqlParser, aSql, m_aAdditiveIterator, *this ); + parseAndCheck_throwError( m_aSqlParser, aSql.makeStringAndClear(), m_aAdditiveIterator, *this ); } catch( const Exception& e ) { @@ -642,7 +649,8 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getTables( ) thro { const OSQLTables& aTables = m_aSqlIterator.getTables(); ::std::vector< ::rtl::OUString> aNames; - for(OSQLTables::const_iterator aIter = aTables.begin(); aIter != aTables.end();++aIter) + OSQLTables::const_iterator aEnd = aTables.end(); + for(OSQLTables::const_iterator aIter = aTables.begin(); aIter != aEnd;++aIter) aNames.push_back(aIter->first); m_pTables = new OPrivateTables(aTables,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames); @@ -674,26 +682,42 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr bCase = m_xMetaData->supportsMixedCaseQuotedIdentifiers(); aSelectColumns = m_aSqlIterator.getSelectColumns(); - ::rtl::OUString sSql = m_aPureSelectSQL; - sSql += STR_WHERE; - sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" 0 = 1 ")); - ::rtl::OUString sGroupBy = getSQLPart(Group,m_aSqlIterator,sal_True); + ::rtl::OUStringBuffer aSQL; + aSQL.append( m_aPureSelectSQL ); + aSQL.append( STR_WHERE ); + + // preserve the original WHERE clause + // #i102234# / 2009-06-02 / frank.schoenheit@sun.com + ::rtl::OUString sOriginalWhereClause = getSQLPart( Where, m_aSqlIterator, sal_False ); + if ( sOriginalWhereClause.getLength() ) + { + aSQL.appendAscii( " ( 0 = 1 ) AND ( " ); + aSQL.append( sOriginalWhereClause ); + aSQL.appendAscii( " ) " ); + } + else + { + aSQL.appendAscii( " ( 0 = 1 ) " ); + } + + ::rtl::OUString sGroupBy = getSQLPart( Group, m_aSqlIterator, sal_True ); if ( sGroupBy.getLength() ) - sSql += sGroupBy; + aSQL.append( sGroupBy ); + ::rtl::OUString sSQL( aSQL.makeStringAndClear() ); // normalize the statement so that it doesn't contain any application-level features anymore ::rtl::OUString sError; - const ::std::auto_ptr< OSQLParseNode > pStatementTree( m_aSqlParser.parseTree( sError, sSql, false ) ); + const ::std::auto_ptr< OSQLParseNode > pStatementTree( m_aSqlParser.parseTree( sError, sSQL, false ) ); DBG_ASSERT( pStatementTree.get(), "OSingleSelectQueryComposer::getColumns: could not parse the column retrieval statement!" ); if ( pStatementTree.get() ) - if ( !pStatementTree->parseNodeToExecutableStatement( sSql, m_xConnection, m_aSqlParser, NULL ) ) + if ( !pStatementTree->parseNodeToExecutableStatement( sSQL, m_xConnection, m_aSqlParser, NULL ) ) break; Reference< XResultSetMetaData > xResultSetMeta; Reference< XResultSetMetaDataSupplier > xResMetaDataSup; try { - xPreparedStatement.set( m_xConnection->prepareStatement( sSql ), UNO_QUERY_THROW ); + xPreparedStatement.set( m_xConnection->prepareStatement( sSQL ), UNO_QUERY_THROW ); xResMetaDataSup.set( xPreparedStatement, UNO_QUERY_THROW ); xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW ); } @@ -705,13 +729,13 @@ Reference< XNameAccess > SAL_CALL OSingleSelectQueryComposer::getColumns( ) thr Reference< XPropertySet > xStatementProps( xStatement, UNO_QUERY_THROW ); try { xStatementProps->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, makeAny( sal_False ) ); } catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } - xResMetaDataSup.set( xStatement->executeQuery( sSql ), UNO_QUERY_THROW ); + xResMetaDataSup.set( xStatement->executeQuery( sSQL ), UNO_QUERY_THROW ); xResultSetMeta.set( xResMetaDataSup->getMetaData(), UNO_QUERY_THROW ); } if ( aSelectColumns->get().empty() ) { - // This is a valid casse. If we can syntactically parse the query, but not semantically + // This is a valid case. If we can syntactically parse the query, but not semantically // (e.g. because it is based on a table we do not know), then there will be no SelectColumns aSelectColumns = ::connectivity::parse::OParseColumn::createColumnsForResultSet( xResultSetMeta, m_xMetaData ); break; @@ -1232,7 +1256,8 @@ Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getParameters( ) { ::vos::ORef< OSQLColumns> aCols = m_aSqlIterator.getParameters(); ::std::vector< ::rtl::OUString> aNames; - for(OSQLColumns::Vector::const_iterator aIter = aCols->get().begin(); aIter != aCols->get().end();++aIter) + OSQLColumns::Vector::const_iterator aEnd = aCols->get().end(); + for(OSQLColumns::Vector::const_iterator aIter = aCols->get().begin(); aIter != aEnd;++aIter) aNames.push_back(getString((*aIter)->getPropertyValue(PROPERTY_NAME))); m_aCurrentColumns[ParameterColumns] = new OPrivateColumns(aCols,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames,sal_True); } @@ -1240,14 +1265,15 @@ Reference< XIndexAccess > SAL_CALL OSingleSelectQueryComposer::getParameters( ) return m_aCurrentColumns[ParameterColumns]; } // ----------------------------------------------------------------------------- -void OSingleSelectQueryComposer::clearParametersCollection() +void OSingleSelectQueryComposer::clearColumns( const EColumnType _eType ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::clearParametersCollection" ); - if ( m_aCurrentColumns[ParameterColumns] ) + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "OSingleSelectQueryComposer::clearColumns" ); + OPrivateColumns* pColumns = m_aCurrentColumns[ _eType ]; + if ( pColumns != NULL ) { - m_aCurrentColumns[ParameterColumns]->disposing(); - m_aColumnsCollection.push_back(m_aCurrentColumns[ParameterColumns]); - m_aCurrentColumns[ParameterColumns] = NULL; + pColumns->disposing(); + m_aColumnsCollection.push_back( pColumns ); + m_aCurrentColumns[ _eType ] = NULL; } } // ----------------------------------------------------------------------------- @@ -1285,7 +1311,8 @@ Reference< XIndexAccess > OSingleSelectQueryComposer::setCurrentColumns( EColumn if ( !m_aCurrentColumns[_eType] ) { ::std::vector< ::rtl::OUString> aNames; - for(OSQLColumns::Vector::const_iterator aIter = _rCols->get().begin(); aIter != _rCols->get().end();++aIter) + OSQLColumns::Vector::const_iterator aEnd = _rCols->get().end(); + for(OSQLColumns::Vector::const_iterator aIter = _rCols->get().begin(); aIter != aEnd;++aIter) aNames.push_back(getString((*aIter)->getPropertyValue(PROPERTY_NAME))); m_aCurrentColumns[_eType] = new OPrivateColumns(_rCols,m_xMetaData->supportsMixedCaseQuotedIdentifiers(),*this,m_aMutex,aNames,sal_True); } @@ -1340,75 +1367,75 @@ namespace { ::rtl::OUString lcl_getCondition(const Sequence< Sequence< PropertyValue > >& filter ) { - ::rtl::OUString sRet; + ::rtl::OUStringBuffer sRet; const Sequence< PropertyValue >* pOrIter = filter.getConstArray(); const Sequence< PropertyValue >* pOrEnd = pOrIter + filter.getLength(); while ( pOrIter != pOrEnd ) { if ( pOrIter->getLength() ) { - sRet += L_BRACKET; + sRet.append(L_BRACKET); const PropertyValue* pAndIter = pOrIter->getConstArray(); const PropertyValue* pAndEnd = pAndIter + pOrIter->getLength(); while ( pAndIter != pAndEnd ) { - sRet += pAndIter->Name; + sRet.append(pAndIter->Name); ::rtl::OUString sValue; pAndIter->Value >>= sValue; switch( pAndIter->Handle ) { case SQLFilterOperator::EQUAL: - sRet += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" = ")); - sRet += sValue; + sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" = "))); + sRet.append(sValue); break; case SQLFilterOperator::NOT_EQUAL: - sRet += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <> ")); - sRet += sValue; + sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <> "))); + sRet.append(sValue); break; case SQLFilterOperator::LESS: - sRet += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" < ")); - sRet += sValue; + sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" < "))); + sRet.append(sValue); break; case SQLFilterOperator::GREATER: - sRet += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" > ")); - sRet += sValue; + sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" > "))); + sRet.append(sValue); break; case SQLFilterOperator::LESS_EQUAL: - sRet += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <= ")); - sRet += sValue; + sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" <= "))); + sRet.append(sValue); break; case SQLFilterOperator::GREATER_EQUAL: - sRet += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" >= ")); - sRet += sValue; + sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" >= "))); + sRet.append(sValue); break; case SQLFilterOperator::LIKE: - sRet += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" LIKE ")); - sRet += sValue; + sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" LIKE "))); + sRet.append(sValue); break; case SQLFilterOperator::NOT_LIKE: - sRet += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" NOT LIKE ")); - sRet += sValue; + sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" NOT LIKE "))); + sRet.append(sValue); break; case SQLFilterOperator::SQLNULL: - sRet += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")) ; + sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NULL")) ); break; case SQLFilterOperator::NOT_SQLNULL: - sRet += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NOT NULL")) ; + sRet.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" IS NOT NULL")) ); break; default: throw IllegalArgumentException(); } ++pAndIter; if ( pAndIter != pAndEnd ) - sRet += STR_AND; + sRet.append(STR_AND); } - sRet += R_BRACKET; + sRet.append(R_BRACKET); } ++pOrIter; if ( pOrIter != pOrEnd && sRet.getLength() ) - sRet += STR_OR; + sRet.append(STR_OR); } - return sRet; + return sRet.makeStringAndClear(); } } // ----------------------------------------------------------------------------- @@ -1431,7 +1458,8 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert if ( !column.is() || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_VALUE) - || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME) ) + || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME) + || !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_TYPE)) throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,Any() ); sal_Int32 nType = 0; @@ -1449,7 +1477,8 @@ void OSingleSelectQueryComposer::setConditionByColumn( const Reference< XPropert column->getPropertyValue(PROPERTY_VALUE) >>= aValue; ::rtl::OUStringBuffer aSQL; - ::rtl::OUString aQuote = m_xMetaData->getIdentifierQuoteString(); + const ::rtl::OUString aQuote = m_xMetaData->getIdentifierQuoteString(); + getColumns(); if ( m_aCurrentColumns[SelectColumns] && m_aCurrentColumns[SelectColumns]->hasByName(aName) ) { |