https://bugs.documentfoundation.org/show_bug.cgi?id=130564
Julien Nabet changed:
What|Removed |Added
CC||lio...@mamane.lu
--- Comment #9 from Julien Nabet ---
After some debugging, here's a code pointer which explains why the creating a
view option only shows when a view exists:
306 // check if we support types
307 if ( xMeta.is() )
308 {
309 Reference xRes = xMeta->getTableTypes();
310 if(xRes.is())
311 {
312 Reference xRow(xRes,UNO_QUERY);
313 while(xRes->next())
314 {
315 OUString sValue = xRow->getString(1);
316 if( !xRow->wasNull() && sValue == "VIEW")
317 {
318 m_bSupportsViews = true;
319 break;
320 }
321 }
322 }
323 // some dbs don't support this type so we should ask if a
XViewsSupplier is supported
324 if(!m_bSupportsViews)
325 {
326 Reference< XViewsSupplier >
xMaster(getMasterTables(),UNO_QUERY);
327
328 if (xMaster.is() && xMaster->getViews().is())
329 m_bSupportsViews = true;
330 }
331 if(m_bSupportsViews)
332 {
333 m_pViews.reset( new OViewContainer(*this, m_aMutex,
this, bCase, this, m_nInAppend) );
334 m_pViews->addContainerListener(m_pTables.get());
335 m_pTables->addContainerListener(m_pViews.get());
336 }
see
https://opengrok.libreoffice.org/xref/core/dbaccess/source/core/dataaccess/connection.cxx?r=bc3a0205#307
getTableTypes is implemented for each database connector so also for ODBC.
Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTableTypes( )
{
Reference< XResultSet > xRef;
try
{
rtl::Reference pResult = new
ODatabaseMetaDataResultSet(m_pConnection);
xRef = pResult;
pResult->openTablesTypes();
}
catch(SQLException&)
{
xRef = new
::connectivity::ODatabaseMetaDataResultSet(::connectivity::ODatabaseMetaDataResultSet::eTableTypes);
}
return xRef;
}
See
https://opengrok.libreoffice.org/xref/core/connectivity/source/drivers/odbc/ODatabaseMetaData.cxx?r=dffe9495#715
It uses "openTablesTypes"
void ODatabaseMetaDataResultSet::openTablesTypes( )
{
SQLRETURN nRetcode = N3SQLTables(m_aStatementHandle,
nullptr,0,
nullptr,0,
nullptr,0,
reinterpret_cast(const_cast(SQL_ALL_TABLE_TYPES)),SQL_NTS);
OTools::ThrowException(m_pConnection.get(),nRetcode,m_aStatementHandle,SQL_HANDLE_STMT,*this);
m_aColMapping.clear();
m_aColMapping.push_back(-1);
m_aColMapping.push_back(4);
m_xMetaData = new
OResultSetMetaData(m_pConnection.get(),m_aStatementHandle,std::vector(m_aColMapping));
checkColumnCount();
}
See
https://opengrok.libreoffice.org/xref/core/connectivity/source/drivers/odbc/ODatabaseMetaDataResultSet.cxx?r=7c3990c3#872
The pb is the ODBC function used
(https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqltables-function?view=sql-server-ver15)
retrieves types from existing elements not types from every elements possible
in a database like original "getTableTypes" from JDBC (see
https://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#getTableTypes()).
So if there's no existing VIEW in the database (Mysql, Postgresql, whatever),
the first method never goes in line 318 ( m_bSupportsViews = true;)
So LO tries another way by calling getMasterTables() and when digging a bit, it
tries to call getDataDefinitionByURLAndConnection()
(See
https://opengrok.libreoffice.org/xref/core/connectivity/source/commontools/dbtools2.cxx?r=d8538d7f#660)
660 Reference< XTablesSupplier> getDataDefinitionByURLAndConnection(
661 const OUString& _rsUrl,
662 const Reference< XConnection>& _xConnection,
663 const Reference< XComponentContext >& _rxContext)
664 {
665 Reference< XTablesSupplier> xTablesSup;
666 try
667 {
668 Reference< XDriverManager2 > xManager = DriverManager::create(
_rxContext );
669 Reference< XDataDefinitionSupplier > xSupp(
xManager->getDriverByURL( _rsUrl ), UNO_QUERY );
670
671 if ( xSupp.is() )
672 {
673 xTablesSup = xSupp->getDataDefinitionByConnection(
_xConnection );
674 OSL_ENSURE(xTablesSup.is(),"No table supplier!");
675 }
676 }
677 catch( const