https://bugs.documentfoundation.org/show_bug.cgi?id=130564
Julien Nabet <serval2...@yahoo.fr> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |lio...@mamane.lu --- Comment #9 from Julien Nabet <serval2...@yahoo.fr> --- 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<XResultSet> xRes = xMeta->getTableTypes(); 310 if(xRes.is()) 311 { 312 Reference<XRow> 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<ODatabaseMetaDataResultSet> 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<SDB_ODBC_CHAR *>(const_cast<char *>(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 Exception& ) 678 { 679 DBG_UNHANDLED_EXCEPTION("connectivity.commontools"); 680 } 681 return xTablesSup; 682 } and finally since ODBC connector in LO doesn't implement XDataDefinitionSupplier, it doesn't go into the "if" and returns empty ref "xTablesSup". So now, what to do? Taking a look how to implement "XDataDefinitionSupplier", it seems we need catalog part, which needs tables part and perhaps views part. I tried this with Mysql direct connector, it takes some time and perhaps there are regressions in what I did. Moreover, calling ODBC functions is less easy than looking into INFORMATION_SCHEMA. A radical (and I suppose wrong) workaround would be in ODatabaseMetaData::getTableTypes from odbc part to just return "VIEW" (in a Reference< XResultSet >) since getTableTypes is only used to know if "VIEW" concept is known. It would mean we'd consider every database which can be accessed from ODBC driver would support VIEWS (!!). Lionel: if you've got some idea here, don't hesitate! :-) -- You are receiving this mail because: You are the assignee for the bug.