Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[datatables] ($store) must be of type SMW\SQLStore\SQLStore, SMW\SPARQLStore\SPARQLStore given #827

Open
simontaurus opened this issue Apr 10, 2024 · 5 comments
Labels

Comments

@simontaurus
Copy link

simontaurus commented Apr 10, 2024

Setup

  • MW version: 1.39.5
  • DB (MySQL etc.): MySQL 8.0.17, blazegraph
  • PHP version: 8.1.27 (apache2handler)
  • SMW version: 4.1.3
  • SRF version: 4.2.1
  • Browsers and versions (if applicable): Firefox

Issue

(@thomas-topway-it)
Sporadically pages with a datatables query throw the mentioned error, probably when a purge is executed but it's hard to reproduce

Exception caught: SMW\SQLStore\QueryEngineFactory::__construct(): Argument #1 ($store) must be of type SMW\SQLStore\SQLStore, SMW\SPARQLStore\SPARQLStore given, called in /var/www/html/w/extensions/SemanticResultFormats/formats/datatables/DataTables.php on line 727

The corresponding line is now in:

$this->queryEngineFactory = new QueryEngineFactory( $this->datatables->store );

Not sure in which cases QueryResult->getStore() returns SMW\SPARQLStore\SPARQLStore in a SPARQLStore setup.

$this->store = $res->getStore();

Workaround is to catch cases where SMW\SPARQLStore\SPARQLStore is given

if ( !( $this->store instanceof \SMW\SQLStore\SQLStore ) ) return [];

Steps to reproduce

  1. Setup with SPARQLStore
  2. Page with datatable ask query
{{#ask: [[Category:A...]]
|?Modification date
|format=datatable
|datatables-searchPanes=true
|datatables-searchPanes.initCollapsed=true
|sort=Modification date
|order=desc
}}
  1. Refresh / purge the page

Expected result: No exception

Observed result: exception occurs:

[e288ba64ad67a5461d8397e1] /wiki/Item:OSW1403aaa3e5ab4... TypeError: SMW\SQLStore\QueryEngineFactory::__construct(): Argument #1 ($store) must be of type SMW\SQLStore\SQLStore, SMW\SPARQLStore\SPARQLStore given, called in /var/www/html/w/extensions/SemanticResultFormats/formats/datatables/DataTables.php on line 725

Backtrace:

from /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngineFactory.php(36)
#0 /var/www/html/w/extensions/SemanticResultFormats/formats/datatables/DataTables.php(725): SMW\SQLStore\QueryEngineFactory->__construct()
#1 /var/www/html/w/extensions/SemanticResultFormats/formats/datatables/DataTables.php(522): SRF\DataTables->getSearchPanes()
#2 /var/www/html/w/extensions/SemanticResultFormats/formats/datatables/DataTables.php(395): SRF\DataTables->getResultText()
#3 /var/www/html/w/extensions/SemanticMediaWiki/src/Query/ResultPrinters/ResultPrinter.php(304): SRF\DataTables->buildResult()
#4 /var/www/html/w/extensions/SemanticMediaWiki/includes/query/SMW_QueryProcessor.php(348): SMW\Query\ResultPrinters\ResultPrinter->getResult()
#5 /var/www/html/w/extensions/SemanticMediaWiki/src/ParserFunctions/AskParserFunction.php(370): SMWQueryProcessor::getResultFromQuery()
#6 /var/www/html/w/extensions/SemanticMediaWiki/src/ParserFunctions/AskParserFunction.php(202): SMW\ParserFunctions\AskParserFunction->doFetchResultsFromFunctionParameters()
#7 /var/www/html/w/extensions/SemanticMediaWiki/src/ParserFunctionFactory.php(402): SMW\ParserFunctions\AskParserFunction->parse()
#8 /var/www/html/w/includes/parser/Parser.php(3437): SMW\ParserFunctionFactory->SMW\{closure}()
#9 /var/www/html/w/includes/parser/Parser.php(3122): Parser->callParserFunction()
#10 /var/www/html/w/includes/parser/PPFrame_Hash.php(275): Parser->braceSubstitution()
#11 /var/www/html/w/extensions/Scribunto/includes/engines/LuaCommon/LuaEngine.php(928): PPFrame_Hash->expand()
#12 /var/www/html/w/extensions/Scribunto/includes/engines/LuaCommon/LuaEngine.php(862): Scribunto_LuaEngine->doCachedExpansion()
#13 /var/www/html/w/extensions/Scribunto/includes/engines/LuaStandalone/LuaStandaloneInterpreter.php(399): Scribunto_LuaEngine->preprocess()
#14 /var/www/html/w/extensions/Scribunto/includes/engines/LuaStandalone/LuaStandaloneInterpreter.php(370): MediaWiki\Extension\Scribunto\Engines\LuaStandalone\LuaStandaloneInterpreter->callback()
#15 /var/www/html/w/extensions/Scribunto/includes/engines/LuaStandalone/LuaStandaloneInterpreter.php(446): MediaWiki\Extension\Scribunto\Engines\LuaStandalone\LuaStandaloneInterpreter->handleCall()
#16 /var/www/html/w/extensions/Scribunto/includes/engines/LuaStandalone/LuaStandaloneInterpreter.php(277): MediaWiki\Extension\Scribunto\Engines\LuaStandalone\LuaStandaloneInterpreter->dispatch()
#17 /var/www/html/w/extensions/Scribunto/includes/engines/LuaCommon/LuaEngine.php(302): MediaWiki\Extension\Scribunto\Engines\LuaStandalone\LuaStandaloneInterpreter->callFunction()
#18 /var/www/html/w/extensions/Scribunto/includes/engines/LuaCommon/LuaModule.php(71): Scribunto_LuaEngine->executeFunctionChunk()
#19 /var/www/html/w/extensions/Scribunto/includes/Hooks.php(158): Scribunto_LuaModule->invoke()
#20 /var/www/html/w/includes/parser/Parser.php(3437): MediaWiki\Extension\Scribunto\Hooks::invokeHook()
#21 /var/www/html/w/includes/parser/Parser.php(3122): Parser->callParserFunction()
#22 /var/www/html/w/includes/parser/PPFrame_Hash.php(275): Parser->braceSubstitution()
#23 /var/www/html/w/includes/parser/Parser.php(2951): PPFrame_Hash->expand()
#24 /var/www/html/w/includes/parser/Parser.php(1609): Parser->replaceVariables()
#25 /var/www/html/w/includes/parser/Parser.php(723): Parser->internalParse()
#26 /var/www/html/w/includes/content/WikitextContentHandler.php(301): Parser->parse()
#27 /var/www/html/w/includes/content/ContentHandler.php(1721): WikitextContentHandler->fillParserOutput()
#28 /var/www/html/w/includes/content/Renderer/ContentRenderer.php(47): ContentHandler->getParserOutput()
#29 /var/www/html/w/includes/Revision/RenderedRevision.php(266): MediaWiki\Content\Renderer\ContentRenderer->getParserOutput()
#30 /var/www/html/w/includes/Revision/RenderedRevision.php(237): MediaWiki\Revision\RenderedRevision->getSlotParserOutputUncached()
#31 /var/www/html/w/includes/Revision/RevisionRenderer.php(236): MediaWiki\Revision\RenderedRevision->getSlotParserOutput()
#32 /var/www/html/w/includes/Revision/RevisionRenderer.php(158): MediaWiki\Revision\RevisionRenderer->combineSlotOutput()
#33 [internal function]: MediaWiki\Revision\RevisionRenderer->MediaWiki\Revision\{closure}()
#34 /var/www/html/w/includes/Revision/RenderedRevision.php(199): call_user_func()
#35 /var/www/html/w/includes/poolcounter/PoolWorkArticleView.php(91): MediaWiki\Revision\RenderedRevision->getRevisionParserOutput()
#36 /var/www/html/w/includes/poolcounter/PoolWorkArticleViewCurrent.php(97): PoolWorkArticleView->renderRevision()
#37 /var/www/html/w/includes/poolcounter/PoolCounterWork.php(162): PoolWorkArticleViewCurrent->doWork()
#38 /var/www/html/w/includes/page/ParserOutputAccess.php(299): PoolCounterWork->execute()
#39 /var/www/html/w/includes/page/Article.php(714): MediaWiki\Page\ParserOutputAccess->getParserOutput()
#40 /var/www/html/w/includes/page/Article.php(528): Article->generateContentOutput()
#41 /var/www/html/w/includes/actions/ViewAction.php(78): Article->view()
#42 /var/www/html/w/includes/MediaWiki.php(542): ViewAction->show()
#43 /var/www/html/w/includes/MediaWiki.php(322): MediaWiki->performAction()
#44 /var/www/html/w/includes/MediaWiki.php(904): MediaWiki->performRequest()
#45 /var/www/html/w/includes/MediaWiki.php(562): MediaWiki->main()
#46 /var/www/html/w/index.php(50): MediaWiki->run()
#47 /var/www/html/w/index.php(46): wfIndexMain()
#48 {main}
@thomas-topway-it
Copy link
Contributor

Hello @simontaurus as far as I understand you are using as SPARQLStore, is that correct ? I haven't tested it directly, however I think that QueryEngineFactory (for it to work) should be a subclass of SMW\SPARQLStore, not SMW\SQLStore. On the other side, a class SMW\SPARQLStore\QueryEngineFactory does not exist.
So first I would need to know whether search panes queries are applicable to the SPARQLStore and they should be implemented for it. If so, we have to look at the class SMW\SPARQLStore\SPARQLStoreFactory (function newMasterQueryEngine), where there is some hint. Otherwise we could just use your workaround to provide an empty result.

@simontaurus
Copy link
Author

Thank you for your response. Correct, I'm using a SPARQLStore.
The missing SMW\SPARQLStore\QueryEngineFactory was also comming up while I was browsing the SMW sources.
Apparently the issue only occurs with |sort=SomePropertyOfTypeDateTime while saving the page edits or purging the page, in all other cases (also normal reloads) everything including the search panels looks fine.
Since |sort=SomePropertyOfTypeDateTime works in principle with other result formats I hope there's a solution.

@krabina krabina added the bug label Apr 17, 2024
@thomas-topway-it
Copy link
Contributor

hello @simontaurus I've checked but I need to test with a SPARQLStore and I don't have it installed right now. Is there any docker container that I can use for this purpose ?

@simontaurus
Copy link
Author

One option would be our docker image / compose-stack

@simontaurus
Copy link
Author

After doing some research on that I still do not understand in which cases SMW passes an SPARQLStore as store and in which cases a SQLStore - it seems random. Maybe @JeroenDeDauw / @kghbln can elaborate on that.

While ElasticStore subclasses SQLStore
https://github.com/SemanticMediaWiki/SemanticMediaWiki/blob/c8f778a85aca38d4d78173c4014f9dc40d067473/src/Elastic/ElasticStore.php#L39

SPARQLStore has a private member that is a SQLStore
https://github.com/SemanticMediaWiki/SemanticMediaWiki/blob/c8f778a85aca38d4d78173c4014f9dc40d067473/src/SPARQLStore/SPARQLStore.php#L49-L66

So theoretically using this basestore should work, but any try to provide a SQLStore as fallback fails, see below.

public function getSearchPanes( $printRequests, $searchPanesOptions ) {
        if ( !( $this->datatables->store instanceof \SMW\SQLStore\SQLStore ) ) { // we got a SPARQLStore
                // $this->datatables->store = new SQLStore(); // fails, see exception
                // $this->datatables->store = \SMW\Services\ServicesFactory::getInstance()->getStore(); // fails, see exception
                // $this->datatables->store = \SMW\StoreFactory::getStore( "\SMW\SQLStore\SQLStore" ); // fails, see exception
                // $this->datatables->store = $this->datatables->store->baseStore; // fails, private property 'baseStore'
                $closure = \Closure::bind(function &(\SMW\SPARQLStore\SPARQLStore $class) { // dirty hack to access private member
                        return $class->baseStore;
                }, null, \SMW\SPARQLStore\SPARQLStore::class);
                $this->datatables->store = &$closure($this->datatables->store); // fails, see exception
        }
}

Exception (may indicate a dirty state on the DB due to a previous exception while playing around with some dirty hacks)

Error 1050: Table 't3' already exists
Function: SMW\SQLStore\TableBuilder\TemporaryTableBuilder::create
Query: CREATE TEMPORARY TABLE `t3`( id INT UNSIGNED KEY ) ENGINE=MEMORY

Backtrace:

from /var/www/html/w/includes/libs/rdbms/database/Database.php(1618)
#0 /var/www/html/w/includes/libs/rdbms/database/Database.php(1602): Wikimedia\Rdbms\Database->getQueryException()
#1 /var/www/html/w/includes/libs/rdbms/database/Database.php(1576): Wikimedia\Rdbms\Database->getQueryExceptionAndLog()
#2 /var/www/html/w/includes/libs/rdbms/database/Database.php(952): Wikimedia\Rdbms\Database->reportQueryError()
#3 /var/www/html/w/includes/libs/rdbms/database/DBConnRef.php(103): Wikimedia\Rdbms\Database->query()
#4 /var/www/html/w/includes/libs/rdbms/database/DBConnRef.php(293): Wikimedia\Rdbms\DBConnRef->__call()
#5 /var/www/html/w/extensions/SemanticMediaWiki/src/MediaWiki/Connection/Database.php(380): Wikimedia\Rdbms\DBConnRef->query()
#6 /var/www/html/w/extensions/SemanticMediaWiki/src/MediaWiki/Connection/Database.php(292): SMW\MediaWiki\Connection\Database->executeQuery()
#7 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/TableBuilder/TemporaryTableBuilder.php(59): SMW\MediaWiki\Connection\Database->query()
#8 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/HierarchyTempTableBuilder.php(111): SMW\SQLStore\TableBuilder\TemporaryTableBuilder->create()
#9 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/QuerySegmentListProcessor.php(355): SMW\SQLStore\QueryEngine\HierarchyTempTableBuilder->fillTempTable()
#10 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/QuerySegmentListProcessor.php(132): SMW\SQLStore\QueryEngine\QuerySegmentListProcessor->hierarchy()
#11 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/QuerySegmentListProcessor.php(146): SMW\SQLStore\QueryEngine\QuerySegmentListProcessor->segment()
#12 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/QuerySegmentListProcessor.php(122): SMW\SQLStore\QueryEngine\QuerySegmentListProcessor->table()
#13 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/QuerySegmentListProcessor.php(220): SMW\SQLStore\QueryEngine\QuerySegmentListProcessor->segment()
#14 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/QuerySegmentListProcessor.php(125): SMW\SQLStore\QueryEngine\QuerySegmentListProcessor->conjunction()
#15 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/QuerySegmentListProcessor.php(146): SMW\SQLStore\QueryEngine\QuerySegmentListProcessor->segment()
#16 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/QuerySegmentListProcessor.php(122): SMW\SQLStore\QueryEngine\QuerySegmentListProcessor->table()
#17 /var/www/html/w/extensions/SemanticMediaWiki/src/SQLStore/QueryEngine/QuerySegmentListProcessor.php(115): SMW\SQLStore\QueryEngine\QuerySegmentListProcessor->segment()
#18 /var/www/html/w/extensions/SemanticResultFormats/formats/datatables/SearchPanes.php(153): SMW\SQLStore\QueryEngine\QuerySegmentListProcessor->process()
#19 /var/www/html/w/extensions/SemanticResultFormats/formats/datatables/SearchPanes.php(85): SRF\DataTables\SearchPanes->getPanesOptions()
#20 /var/www/html/w/extensions/SemanticResultFormats/formats/datatables/DataTables.php(586): SRF\DataTables\SearchPanes->getSearchPanes()
#21 /var/www/html/w/extensions/SemanticResultFormats/formats/datatables/DataTables.php(440): SRF\DataTables->getResultText()
#22 /var/www/html/w/extensions/SemanticMediaWiki/src/Query/ResultPrinters/ResultPrinter.php(304): SRF\DataTables->buildResult()
#23 /var/www/html/w/extensions/SemanticMediaWiki/includes/query/SMW_QueryProcessor.php(348): SMW\Query\ResultPrinters\ResultPrinter->getResult()
#24 /var/www/html/w/extensions/SemanticMediaWiki/src/ParserFunctions/AskParserFunction.php(370): SMWQueryProcessor::getResultFromQuery()
#25 /var/www/html/w/extensions/SemanticMediaWiki/src/ParserFunctions/AskParserFunction.php(202): SMW\ParserFunctions\AskParserFunction->doFetchResultsFromFunctionParameters()
#26 /var/www/html/w/extensions/SemanticMediaWiki/src/ParserFunctionFactory.php(402): SMW\ParserFunctions\AskParserFunction->parse()
#27 /var/www/html/w/includes/parser/Parser.php(3437): SMW\ParserFunctionFactory->SMW\{closure}()
#28 /var/www/html/w/includes/parser/Parser.php(3122): Parser->callParserFunction()
#29 /var/www/html/w/includes/parser/PPFrame_Hash.php(275): Parser->braceSubstitution()
#30 /var/www/html/w/includes/parser/Parser.php(2951): PPFrame_Hash->expand()
#31 /var/www/html/w/includes/parser/Parser.php(1609): Parser->replaceVariables()
#32 /var/www/html/w/includes/parser/Parser.php(723): Parser->internalParse()
#33 /var/www/html/w/includes/content/WikitextContentHandler.php(301): Parser->parse()
#34 /var/www/html/w/includes/content/ContentHandler.php(1721): WikitextContentHandler->fillParserOutput()
#35 /var/www/html/w/includes/content/Renderer/ContentRenderer.php(47): ContentHandler->getParserOutput()
#36 /var/www/html/w/includes/Revision/RenderedRevision.php(266): MediaWiki\Content\Renderer\ContentRenderer->getParserOutput()
#37 /var/www/html/w/includes/Revision/RenderedRevision.php(237): MediaWiki\Revision\RenderedRevision->getSlotParserOutputUncached()
#38 /var/www/html/w/includes/Revision/RevisionRenderer.php(221): MediaWiki\Revision\RenderedRevision->getSlotParserOutput()
#39 /var/www/html/w/includes/Revision/RevisionRenderer.php(158): MediaWiki\Revision\RevisionRenderer->combineSlotOutput()
#40 [internal function]: MediaWiki\Revision\RevisionRenderer->MediaWiki\Revision\{closure}()
#41 /var/www/html/w/includes/Revision/RenderedRevision.php(199): call_user_func()
#42 /var/www/html/w/includes/poolcounter/PoolWorkArticleView.php(91): MediaWiki\Revision\RenderedRevision->getRevisionParserOutput()
#43 /var/www/html/w/includes/poolcounter/PoolWorkArticleViewCurrent.php(97): PoolWorkArticleView->renderRevision()
#44 /var/www/html/w/includes/poolcounter/PoolCounterWork.php(162): PoolWorkArticleViewCurrent->doWork()
#45 /var/www/html/w/includes/page/ParserOutputAccess.php(299): PoolCounterWork->execute()
#46 /var/www/html/w/includes/page/Article.php(714): MediaWiki\Page\ParserOutputAccess->getParserOutput()
#47 /var/www/html/w/includes/page/Article.php(528): Article->generateContentOutput()
#48 /var/www/html/w/includes/actions/ViewAction.php(78): Article->view()
#49 /var/www/html/w/includes/MediaWiki.php(542): ViewAction->show()
#50 /var/www/html/w/includes/MediaWiki.php(322): MediaWiki->performAction()
#51 /var/www/html/w/includes/MediaWiki.php(904): MediaWiki->performRequest()
#52 /var/www/html/w/includes/MediaWiki.php(562): MediaWiki->main()
#53 /var/www/html/w/index.php(50): MediaWiki->run()
#54 /var/www/html/w/index.php(46): wfIndexMain()
#55 {main}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants