ORDER BY columns are prioritarily *SELECT* columns
as opposed to *table* columns, and notwithstanding HSQLDB 1.8 (our embedded database) bugs. Actually, supporting ORDER BY on non-select (but table) columns is OPTIONAL for DBMSs (but quite common) Change-Id: I6725dfda36b09429a78262bff6f3d3e3dd9032b6
This commit is contained in:
@@ -1868,7 +1868,9 @@ OUString OSQLParseTreeIterator::getUniqueColumnName(const OUString & rColumnName
|
|||||||
void OSQLParseTreeIterator::setOrderByColumnName(const OUString & rColumnName, OUString & rTableRange, sal_Bool bAscending)
|
void OSQLParseTreeIterator::setOrderByColumnName(const OUString & rColumnName, OUString & rTableRange, sal_Bool bAscending)
|
||||||
{
|
{
|
||||||
SAL_INFO( "connectivity.parse", "parse Ocke.Janssen@sun.com OSQLParseTreeIterator::setOrderByColumnName" );
|
SAL_INFO( "connectivity.parse", "parse Ocke.Janssen@sun.com OSQLParseTreeIterator::setOrderByColumnName" );
|
||||||
Reference<XPropertySet> xColumn = findColumn( rColumnName, rTableRange, false );
|
Reference<XPropertySet> xColumn = findSelectColumn( rColumnName );
|
||||||
|
if ( !xColumn.is() )
|
||||||
|
xColumn = findColumn ( rColumnName, rTableRange, false );
|
||||||
if ( xColumn.is() )
|
if ( xColumn.is() )
|
||||||
m_aOrderColumns->get().push_back(new OOrderColumn( xColumn, rTableRange, isCaseSensitive(), bAscending ) );
|
m_aOrderColumns->get().push_back(new OOrderColumn( xColumn, rTableRange, isCaseSensitive(), bAscending ) );
|
||||||
else
|
else
|
||||||
@@ -2045,6 +2047,30 @@ const OSQLParseNode* OSQLParseTreeIterator::getSimpleHavingTree() const
|
|||||||
return pNode ? pNode->getChild(1) : NULL;
|
return pNode ? pNode->getChild(1) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
Reference< XPropertySet > OSQLParseTreeIterator::findSelectColumn( const OUString & rColumnName )
|
||||||
|
{
|
||||||
|
SAL_INFO( "connectivity.parse", "parse lionel@mamane.lu OSQLParseTreeIterator::findSelectColumn" );
|
||||||
|
for ( OSQLColumns::Vector::const_iterator lookupColumn = m_aSelectColumns->get().begin();
|
||||||
|
lookupColumn != m_aSelectColumns->get().end();
|
||||||
|
++lookupColumn )
|
||||||
|
{
|
||||||
|
Reference< XPropertySet > xColumn( *lookupColumn );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OUString sName, sTableName;
|
||||||
|
xColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_NAME ) ) >>= sName;
|
||||||
|
if ( sName == rColumnName )
|
||||||
|
return xColumn;
|
||||||
|
}
|
||||||
|
catch( const Exception& )
|
||||||
|
{
|
||||||
|
DBG_UNHANDLED_EXCEPTION();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
Reference< XPropertySet > OSQLParseTreeIterator::findColumn( const OUString & rColumnName, OUString & rTableRange, bool _bLookInSubTables )
|
Reference< XPropertySet > OSQLParseTreeIterator::findColumn( const OUString & rColumnName, OUString & rTableRange, bool _bLookInSubTables )
|
||||||
{
|
{
|
||||||
|
@@ -456,7 +456,7 @@ void SAL_CALL OSingleSelectQueryComposer::appendFilterByColumn( const Reference<
|
|||||||
setConditionByColumn(column,andCriteria,F_tmp,filterOperator);
|
setConditionByColumn(column,andCriteria,F_tmp,filterOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
OUString OSingleSelectQueryComposer::impl_getColumnName_throw(const Reference< XPropertySet >& column)
|
OUString OSingleSelectQueryComposer::impl_getColumnRealName_throw(const Reference< XPropertySet >& column, bool bGroupBy)
|
||||||
{
|
{
|
||||||
::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
|
::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
|
||||||
|
|
||||||
@@ -471,17 +471,18 @@ OUString OSingleSelectQueryComposer::impl_getColumnName_throw(const Reference< X
|
|||||||
throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,makeAny(aErr) );
|
throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,makeAny(aErr) );
|
||||||
}
|
}
|
||||||
|
|
||||||
OUString aName,aNewName;
|
OUString aName, aNewName;
|
||||||
column->getPropertyValue(PROPERTY_NAME) >>= aName;
|
column->getPropertyValue(PROPERTY_NAME) >>= aName;
|
||||||
|
|
||||||
if ( !m_xMetaData->supportsOrderByUnrelated() && m_aCurrentColumns[SelectColumns] && !m_aCurrentColumns[SelectColumns]->hasByName(aName))
|
if ( bGroupBy &&
|
||||||
|
!m_xMetaData->supportsGroupByUnrelated() &&
|
||||||
|
m_aCurrentColumns[SelectColumns] &&
|
||||||
|
!m_aCurrentColumns[SelectColumns]->hasByName(aName) )
|
||||||
{
|
{
|
||||||
OUString sError(DBACORE_RESSTRING(RID_STR_COLUMN_MUST_VISIBLE));
|
OUString sError(DBACORE_RESSTRING(RID_STR_COLUMN_MUST_VISIBLE));
|
||||||
throw SQLException(sError.replaceAll("%name", aName),*this,SQLSTATE_GENERAL,1000,Any() );
|
throw SQLException(sError.replaceAll("%name", aName),*this,SQLSTATE_GENERAL,1000,Any() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach filter
|
|
||||||
// Construct SELECT without WHERE and ORDER BY
|
|
||||||
OUString aQuote = m_xMetaData->getIdentifierQuoteString();
|
OUString aQuote = m_xMetaData->getIdentifierQuoteString();
|
||||||
if ( m_aCurrentColumns[SelectColumns]->hasByName(aName) )
|
if ( m_aCurrentColumns[SelectColumns]->hasByName(aName) )
|
||||||
{
|
{
|
||||||
@@ -491,7 +492,7 @@ OUString OSingleSelectQueryComposer::impl_getColumnName_throw(const Reference< X
|
|||||||
OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!");
|
OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_TABLENAME),"Property TABLENAME not available!");
|
||||||
OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName("Function"),"Property FUNCTION not available!");
|
OSL_ENSURE(xColumn->getPropertySetInfo()->hasPropertyByName("Function"),"Property FUNCTION not available!");
|
||||||
|
|
||||||
OUString sRealName,sTableName;
|
OUString sRealName, sTableName;
|
||||||
xColumn->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
|
xColumn->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
|
||||||
xColumn->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName;
|
xColumn->getPropertyValue(PROPERTY_TABLENAME) >>= sTableName;
|
||||||
sal_Bool bFunction = sal_False;
|
sal_Bool bFunction = sal_False;
|
||||||
@@ -525,11 +526,43 @@ OUString OSingleSelectQueryComposer::impl_getColumnName_throw(const Reference< X
|
|||||||
return aNewName;
|
return aNewName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OUString OSingleSelectQueryComposer::impl_getColumnName_throw(const Reference< XPropertySet >& column, bool bOrderBy)
|
||||||
|
{
|
||||||
|
::connectivity::checkDisposed(OSubComponent::rBHelper.bDisposed);
|
||||||
|
|
||||||
|
getColumns();
|
||||||
|
if ( !column.is()
|
||||||
|
|| !m_aCurrentColumns[SelectColumns]
|
||||||
|
|| !column->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
OUString sError(DBACORE_RESSTRING(RID_STR_COLUMN_UNKNOWN_PROP));
|
||||||
|
SQLException aErr(sError.replaceAll("%value", OUString(PROPERTY_NAME)),*this,SQLSTATE_GENERAL,1000,Any() );
|
||||||
|
throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_NOT_VALID),*this,SQLSTATE_GENERAL,1000,makeAny(aErr) );
|
||||||
|
}
|
||||||
|
|
||||||
|
OUString aName, aNewName;
|
||||||
|
column->getPropertyValue(PROPERTY_NAME) >>= aName;
|
||||||
|
|
||||||
|
if ( bOrderBy &&
|
||||||
|
!m_xMetaData->supportsOrderByUnrelated() &&
|
||||||
|
m_aCurrentColumns[SelectColumns] &&
|
||||||
|
!m_aCurrentColumns[SelectColumns]->hasByName(aName) )
|
||||||
|
{
|
||||||
|
OUString sError(DBACORE_RESSTRING(RID_STR_COLUMN_MUST_VISIBLE));
|
||||||
|
throw SQLException(sError.replaceAll("%name", aName),*this,SQLSTATE_GENERAL,1000,Any() );
|
||||||
|
}
|
||||||
|
|
||||||
|
const OUString aQuote = m_xMetaData->getIdentifierQuoteString();
|
||||||
|
aNewName = ::dbtools::quoteName(aQuote,aName);
|
||||||
|
return aNewName;
|
||||||
|
}
|
||||||
|
|
||||||
void SAL_CALL OSingleSelectQueryComposer::appendOrderByColumn( const Reference< XPropertySet >& column, sal_Bool ascending ) throw(SQLException, RuntimeException)
|
void SAL_CALL OSingleSelectQueryComposer::appendOrderByColumn( const Reference< XPropertySet >& column, sal_Bool ascending ) throw(SQLException, RuntimeException)
|
||||||
{
|
{
|
||||||
SAL_INFO("dbaccess", "OSingleSelectQueryComposer::appendOrderByColumn" );
|
SAL_INFO("dbaccess", "OSingleSelectQueryComposer::appendOrderByColumn" );
|
||||||
::osl::MutexGuard aGuard( m_aMutex );
|
::osl::MutexGuard aGuard( m_aMutex );
|
||||||
OUString sColumnName( impl_getColumnName_throw(column) );
|
OUString sColumnName( impl_getColumnName_throw(column, true) );
|
||||||
OUString sOrder = getOrder();
|
OUString sOrder = getOrder();
|
||||||
if ( !(sOrder.isEmpty() || sColumnName.isEmpty()) )
|
if ( !(sOrder.isEmpty() || sColumnName.isEmpty()) )
|
||||||
sOrder += COMMA;
|
sOrder += COMMA;
|
||||||
@@ -544,7 +577,7 @@ void SAL_CALL OSingleSelectQueryComposer::appendGroupByColumn( const Reference<
|
|||||||
{
|
{
|
||||||
SAL_INFO("dbaccess", "OSingleSelectQueryComposer::appendGroupByColumn" );
|
SAL_INFO("dbaccess", "OSingleSelectQueryComposer::appendGroupByColumn" );
|
||||||
::osl::MutexGuard aGuard( m_aMutex );
|
::osl::MutexGuard aGuard( m_aMutex );
|
||||||
OUString sColumnName( impl_getColumnName_throw(column) );
|
OUString sColumnName( impl_getColumnRealName_throw(column, true) );
|
||||||
OrderCreator aComposer;
|
OrderCreator aComposer;
|
||||||
aComposer.append( getGroup() );
|
aComposer.append( getGroup() );
|
||||||
aComposer.append( sColumnName );
|
aComposer.append( sColumnName );
|
||||||
|
@@ -180,9 +180,25 @@ namespace dbaccess
|
|||||||
*/
|
*/
|
||||||
OUString composeStatementFromParts( const ::std::vector< OUString >& _rParts );
|
OUString composeStatementFromParts( const ::std::vector< OUString >& _rParts );
|
||||||
|
|
||||||
/** return the name of the column.
|
/** return the name of the column in the *source* *table*.
|
||||||
|
|
||||||
|
That is, for (SELECT a AS b FROM t), it returns A or "t"."A", as appropriate.
|
||||||
|
|
||||||
|
Use e.g. for WHERE, GROUP BY and HAVING clauses.
|
||||||
|
|
||||||
|
@param bGroupBy: for GROUP BY clause? In that case, throw exception if trying to use an unrelated column and the database does not support that.
|
||||||
*/
|
*/
|
||||||
OUString impl_getColumnName_throw(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column);
|
OUString impl_getColumnRealName_throw(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column, bool bGroupBy);
|
||||||
|
|
||||||
|
/** return the name of the column in the *query*
|
||||||
|
|
||||||
|
That is, for (SELECT a AS b FROM t), it returns "b"
|
||||||
|
|
||||||
|
Use e.g. for ORDER BY clause.
|
||||||
|
|
||||||
|
@param bOrderBy: for ORDER BY clause? In that case, throw exception if trying to use an unrelated column and the database does not support that.
|
||||||
|
*/
|
||||||
|
OUString impl_getColumnName_throw(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& column, bool bOrderBy);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~OSingleSelectQueryComposer();
|
virtual ~OSingleSelectQueryComposer();
|
||||||
|
@@ -234,30 +234,7 @@ OUString DlgOrderCrit::GetOrderList( ) const
|
|||||||
sOrder += OUString(",");
|
sOrder += OUString(",");
|
||||||
|
|
||||||
String sName = m_aColumnList[i]->GetSelectEntry();
|
String sName = m_aColumnList[i]->GetSelectEntry();
|
||||||
try
|
sOrder += ::dbtools::quoteName(sQuote,sName);
|
||||||
{
|
|
||||||
sal_Bool bFunction = sal_False;
|
|
||||||
Reference< XPropertySet > xColumn;
|
|
||||||
if ( xColumns.is() && xColumns->hasByName( sName ) && (xColumns->getByName( sName ) >>= xColumn) && xColumn.is() )
|
|
||||||
{
|
|
||||||
if ( xColumn->getPropertySetInfo()->hasPropertyByName(PROPERTY_REALNAME) )
|
|
||||||
{
|
|
||||||
OUString sRealName;
|
|
||||||
xColumn->getPropertyValue(PROPERTY_REALNAME) >>= sRealName;
|
|
||||||
sName = sRealName;
|
|
||||||
static OUString sFunction("Function");
|
|
||||||
if ( xColumn->getPropertySetInfo()->hasPropertyByName(sFunction) )
|
|
||||||
xColumn->getPropertyValue(sFunction) >>= bFunction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( bFunction )
|
|
||||||
sOrder += sName;
|
|
||||||
else
|
|
||||||
sOrder += ::dbtools::quoteName(sQuote,sName);
|
|
||||||
}
|
|
||||||
catch(const Exception&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
if(m_aValueList[i]->GetSelectEntryPos())
|
if(m_aValueList[i]->GetSelectEntryPos())
|
||||||
sOrder += sDESC;
|
sOrder += sDESC;
|
||||||
else
|
else
|
||||||
|
@@ -111,6 +111,14 @@ namespace connectivity
|
|||||||
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findColumn(
|
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findColumn(
|
||||||
const OUString & rColumnName, OUString & rTableRange, bool _bLookInSubTables );
|
const OUString & rColumnName, OUString & rTableRange, bool _bLookInSubTables );
|
||||||
|
|
||||||
|
/** finds a column with a given name among the select columns
|
||||||
|
@param rColumnName
|
||||||
|
the column name to look for
|
||||||
|
@return
|
||||||
|
*/
|
||||||
|
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findSelectColumn(
|
||||||
|
const OUString & rColumnName );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setSelectColumnName(::rtl::Reference<OSQLColumns>& _rColumns,const OUString & rColumnName,const OUString & rColumnAlias, const OUString & rTableRange,sal_Bool bFkt=sal_False,sal_Int32 _nType = com::sun::star::sdbc::DataType::VARCHAR,sal_Bool bAggFkt=sal_False);
|
void setSelectColumnName(::rtl::Reference<OSQLColumns>& _rColumns,const OUString & rColumnName,const OUString & rColumnAlias, const OUString & rTableRange,sal_Bool bFkt=sal_False,sal_Int32 _nType = com::sun::star::sdbc::DataType::VARCHAR,sal_Bool bAggFkt=sal_False);
|
||||||
void appendColumns(::rtl::Reference<OSQLColumns>& _rColumns,const OUString& _rTableAlias,const OSQLTable& _rTable);
|
void appendColumns(::rtl::Reference<OSQLColumns>& _rColumns,const OUString& _rTableAlias,const OSQLTable& _rTable);
|
||||||
|
Reference in New Issue
Block a user