summaryrefslogtreecommitdiff
path: root/dbaccess/source/core/api/KeySet.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'dbaccess/source/core/api/KeySet.cxx')
-rw-r--r--dbaccess/source/core/api/KeySet.cxx70
1 files changed, 41 insertions, 29 deletions
diff --git a/dbaccess/source/core/api/KeySet.cxx b/dbaccess/source/core/api/KeySet.cxx
index 6ee7a2b8ea4c..5de2c497c031 100644
--- a/dbaccess/source/core/api/KeySet.cxx
+++ b/dbaccess/source/core/api/KeySet.cxx
@@ -197,9 +197,10 @@ void OKeySet::initColumns()
m_pParameterNames.reset( new SelectColumnsMetaData(bCase) );
m_pForeignColumnNames.reset( new SelectColumnsMetaData(bCase) );
}
-void OKeySet::findTableColumnsMatching_throw(const Any& i_aTable
- ,const Reference<XDatabaseMetaData>& i_xMeta
- ,const Reference<XNameAccess>& i_xQueryColumns)
+void OKeySet::findTableColumnsMatching_throw( const Any& i_aTable,
+ const ::rtl::OUString& i_rUpdateTableName,
+ const Reference<XDatabaseMetaData>& i_xMeta,
+ const Reference<XNameAccess>& i_xQueryColumns)
{
// first ask the database itself for the best columns which can be used
Sequence< ::rtl::OUString> aBestColumnNames;
@@ -220,37 +221,48 @@ void OKeySet::findTableColumnsMatching_throw(const Any& i_aTable
xPara->getPropertyValue(PROPERTY_REALNAME) >>= aParameterColumns[i];
}
- if ( m_sUpdateTableName.getLength() )
+ ::rtl::OUString sUpdateTableName( i_rUpdateTableName );
+ if ( sUpdateTableName.getLength() == 0 )
{
- ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,m_sUpdateTableName,(*m_pKeyColumnNames),true);
- ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),m_sUpdateTableName,(*m_pColumnNames),true);
- ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,m_sUpdateTableName,(*m_pParameterNames),true);
+ OSL_ENSURE( false, "OKeySet::findTableColumnsMatching_throw: This is a fallback only - it won't work when the table has an alias name." );
+ // If i_aTable originates from a query composer, and is a table which appears with an alias in the SELECT statement,
+ // then the below code will not produce correct results.
+ // For instance, imagine a "SELECT alias.col FROM table AS alias". Now i_aTable would be the table named
+ // "table", so our sUpdateTableName would be "table" as well - not the information about the "alias" is
+ // already lost here.
+ // now getColumnPositions would travers the columns, and check which of them belong to the table denoted
+ // by sUpdateTableName. Since the latter is "table", but the columns only know that they belong to a table
+ // named "alias", there will be no matching - so getColumnPositions wouldn't find anything.
+
+ ::rtl::OUString sCatalog, sSchema, sTable;
+ Reference<XPropertySet> xTableProp( i_aTable, UNO_QUERY_THROW );
+ xTableProp->getPropertyValue( PROPERTY_CATALOGNAME )>>= sCatalog;
+ xTableProp->getPropertyValue( PROPERTY_SCHEMANAME ) >>= sSchema;
+ xTableProp->getPropertyValue( PROPERTY_NAME ) >>= sTable;
+ sUpdateTableName = dbtools::composeTableName( i_xMeta, sCatalog, sSchema, sTable, sal_False, ::dbtools::eInDataManipulation );
}
- else
+
+ ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,sUpdateTableName,(*m_pKeyColumnNames),true);
+ ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),sUpdateTableName,(*m_pColumnNames),true);
+ ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,sUpdateTableName,(*m_pParameterNames),true);
+
+ if ( m_pKeyColumnNames->empty() )
{
- ::rtl::OUString sCatalog,sSchema,sTable;
- Reference<XPropertySet> xTableProp(i_aTable,UNO_QUERY);
- Any aCatalog = xTableProp->getPropertyValue(PROPERTY_CATALOGNAME);
- aCatalog >>= sCatalog;
- xTableProp->getPropertyValue(PROPERTY_SCHEMANAME) >>= sSchema;
- xTableProp->getPropertyValue(PROPERTY_NAME) >>= sTable;
- const ::rtl::OUString sComposedUpdateTableName = dbtools::composeTableName( i_xMeta, sCatalog, sSchema, sTable, sal_False, ::dbtools::eInDataManipulation );
- ::dbaccess::getColumnPositions(i_xQueryColumns,aBestColumnNames,sComposedUpdateTableName,(*m_pKeyColumnNames),true);
- ::dbaccess::getColumnPositions(i_xQueryColumns,xTblColumns->getElementNames(),sComposedUpdateTableName,(*m_pColumnNames),true);
- ::dbaccess::getColumnPositions(i_xQueryColumns,aParameterColumns,sComposedUpdateTableName,(*m_pParameterNames),true);
+ ::dbtools::throwGenericSQLException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not find any key column." ) ), *this );
}
- SelectColumnsMetaData::const_iterator aPosIter = m_pKeyColumnNames->begin();
- SelectColumnsMetaData::const_iterator aPosEnd = m_pKeyColumnNames->end();
- for(;aPosIter != aPosEnd;++aPosIter)
+ for ( SelectColumnsMetaData::const_iterator keyColumn = m_pKeyColumnNames->begin();
+ keyColumn != m_pKeyColumnNames->end();
+ ++keyColumn
+ )
{
- if ( xTblColumns->hasByName(aPosIter->second.sRealName) )
- {
- Reference<XPropertySet> xProp(xTblColumns->getByName(aPosIter->second.sRealName),UNO_QUERY);
- sal_Bool bAuto = sal_False;
- if( (xProp->getPropertyValue(PROPERTY_ISAUTOINCREMENT) >>= bAuto) && bAuto)
- m_aAutoColumns.push_back(aPosIter->first);
- }
+ if ( !xTblColumns->hasByName( keyColumn->second.sRealName ) )
+ continue;
+
+ Reference<XPropertySet> xProp( xTblColumns->getByName( keyColumn->second.sRealName ), UNO_QUERY );
+ sal_Bool bAuto = sal_False;
+ if ( ( xProp->getPropertyValue( PROPERTY_ISAUTOINCREMENT ) >>= bAuto ) && bAuto )
+ m_aAutoColumns.push_back( keyColumn->first );
}
}
::rtl::OUStringBuffer OKeySet::createKeyFilter()
@@ -286,7 +298,7 @@ void OKeySet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::O
Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
Reference<XColumnsSupplier> xQueryColSup(m_xComposer,UNO_QUERY);
const Reference<XNameAccess> xQueryColumns = xQueryColSup->getColumns();
- findTableColumnsMatching_throw(makeAny(m_xTable),xMeta,xQueryColumns);
+ findTableColumnsMatching_throw(makeAny(m_xTable),m_sUpdateTableName,xMeta,xQueryColumns);
// the first row is empty because it's now easier for us to distinguish when we are beforefirst or first
// without extra varaible to be set