Sparql существует функция, не работающая с привязкой, если

Мой виртуоз (virtuoso-t -h):

Virtuoso Open Source Edition (Column Store) (multi threaded)
Version 7.2.4.2.3217-pthreads as of Jun  3 2016
Compiled for Linux (x86_64-pc-linux-gnu)

Функция Sparql exists работает нормально, но не в сочетании с (bind if(...)).
Запрос:

PREFIX dbo: <http://dbpedia.org/property/>
SELECT  ?uri  ?popEstimate ?existsPopEstim ?usedExPop
WHERE {
    ?uri  a <http://dbpedia.org/ontology/Place>.

    {?uri rdfs:label "France"@fr}
    UNION {?uri rdfs:label "Brésil"@fr}
    UNION {?uri rdfs:label "Amérique"@fr}

    OPTIONAL {?uri dbo:populationEstimate ?popEstimate .}   
    BIND (exists{?uri dbo:populationEstimate ?popEstimate} AS ?existsPopEstim )
    BIND (IF(?existsPopEstim , "ok", "no") AS ?usedExPop)
}
LIMIT 100

Результат:

uri                                  | popEstimate | existsPopEstim | usedExPop
-------------------------------------+-------------+----------------+----------
http://dbpedia.org/resource/France   |             | 0              | ok
http://dbpedia.org/resource/Brazil   | 201032714   | 1              | ok
http://dbpedia.org/resource/Americas |             | 0              | ok 

Изменить 1

Пример из ответа @AKSW, который также не работает на https://dbpedia.org/sparql:

PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
SELECT *
WHERE {
    ?uri a dbo:SoccerPlayer
    OPTIONAL {?uri dbo:deathDate ?date}
    BIND (exists{?uri dbo:deathDate ?date} AS ?existsProp )
    BIND (IF(?existsProp , "ok", "no") AS ?usedExProp) }
LIMIT 1000

Изменить 2. Пример на dbpedia: http://dbpedia.org/sparql/?default-graph-uri=&query=PREFIX+dbo%3A+%3Chttp%3A%2F%2Fdbpedia.org%2Fproperty%2F%3E%0D%0APREFIX+xsd%3A+%3Chttps%3A%2F%2Fwww.w3.org%2F2009%2FXMLSchema%2F%3E%0D%0APREFIX+dbo%3A+%3Chttp%3A%2Fdbpedia.org%2Fontology%2F%3E%0D%0APREFIX+rdfs%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0D%0A%0D%0ASELECT++%3Furi++%3Fpop+%3FexistsPop+%3FusedExPop%0D%0AWHERE+%7B%0D%0A%09%3Furi++a+%3Chttp%3A%2F%2Fdbpedia.org%2Fontology%2FPlace%3E.%0D%0A%09%0D%0A%09%7B%3Furi+rdfs%3Alabel+%22France%22%40en%7D%0D%0A%09UNION+%7B%3Furi+rdfs%3Alabel+%22Brazil%22%40en%7D%0D%0A%09UNION+%7B%3Furi+rdfs%3Alabel+%22Raging+River%22%40en%7D%0D%0A%0D%0A%09OPTIONAL+%7B%3Furi+dbo%3ApopulationTotal+%3Fpop+.%7D%09%0D%0A%09BIND+%28exists%7B%3Furi+dbo%3ApopulationTotal+%3Fpop%7D+AS+%3FexistsPop%29%0D%0A%09BIND+%28IF%28%3FexistsPop%2C+%22ok%22%2C+%22no%22%29+AS+%3FusedExPop%29%0D%0A%7D%0D%0ALIMIT+1000&format=text%2Fhtml&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=3000000&run=+Run+Query+


person Kévin Darty    schedule 07.11.2017    source источник
comment
Должна быть ошибка в соответствии с вашим примером. Вы должны сообщить об этом в список рассылки Virtuoso. Больше здесь никто не может.   -  person UninformedUser    schedule 07.11.2017
comment
Незначительные комментарии: Используйте SPARQL 1.1 VALUES и будьте осторожны с префиксами. Адаптированный запрос: PREFIX dbo: <http://dbpedia.org/ontology/> PREFIX dbp: <http://dbpedia.org/property/> SELECT * WHERE { VALUES ?label {"France"@fr "Brésil"@fr "Amérique"@fr} ?uri a dbo:Place ; rdfs:label ?label OPTIONAL {?uri dbp:populationEstimate ?popEstimate} BIND (exists{?uri dbp:populationEstimate ?popEstimate} AS ?existsPopEstim ) BIND (IF(?existsPopEstim , "ok", "no") AS ?usedExPop) } LIMIT 100   -  person UninformedUser    schedule 07.11.2017
comment
Также может быть воспроизведен на общедоступной конечной точке DBpedia: SELECT * WHERE { ?uri a dbo:SoccerPlayer OPTIONAL {?uri dbo:deathDate ?date} BIND (exists{?uri dbo:deathDate ?date} AS ?existsProp ) BIND (IF(?existsProp , "ok", "no") AS ?usedExProp) } Он всегда возвращает "нет", за исключением первой строки: http://dbpedia.org/resource/Fritz_Walter 2002-06-17 1 ok   -  person UninformedUser    schedule 07.11.2017
comment
Спасибо за ответы @AKSW. Я добавил ваш последний пример, который хорошо показывает, что проблема реальна и находится на стороне Virtuoso.   -  person Kévin Darty    schedule 08.11.2017
comment
@Niii, bound отлично работает в DBpedia: попробуйте BIND (bound(?pop) AS ?exists1Pop) . BIND (IF(?exists1Pop , "ok", "no") AS ?usedEx1Pop) и т. Д.   -  person Stanislav Kralin    schedule 09.11.2017


Ответы (2)


Я заметил, что вы столкнулись с этой проблемой в версии 7.2.4.2.3217-pthreads по состоянию на 3 июня 2016 года. Вот что происходит с более свежими выпусками 7.2.x и 8.0 по ссылкам на живые примеры:

person Kingsley Uyi Idehen    schedule 07.11.2017
comment
Добавленный в настоящее время FROM CLAUSE выявляет проблему, т.е. комментирование FROM CLAUSE является временным решением. - person Kingsley Uyi Idehen; 07.11.2017
comment
Как @AKSW демонстрирует на другом примере, эта проблема возникает даже в текущей конечной точке DBPedia. - person Kévin Darty; 08.11.2017
comment
@Niii Kingsley уже сказал, что проблему можно воссоздать. Обходной путь - удалить предложение FROM, т.е. не использовать график по умолчанию. - person UninformedUser; 08.11.2017
comment
С предложением FROM или без него и с графиком по умолчанию или без него результат для меня такой же. - person Kévin Darty; 09.11.2017

Кажется, это виртуозная проблема с типом данных, как сказал @Kingsley, см. https://github.com/openlink/virtuoso-opensource/issues/693

person Kévin Darty    schedule 08.11.2017
comment
Да, в конечном итоге эта проблема возникает из базового ядра SQL (на котором реализован SPARQL). Доказательство: SELECT CASE WHEN (COALESCE ((SELECT TOP 1 1 FROM DB.DBA.SYS_USERS WHERE U_NAME = ''), 0)) THEN ('ok') ELSE ('no') end; возвращает ОК, тогда как SELECT COALESCE ((SELECT TOP 1 1 FROM DB.DBA.SYS_USERS WHERE U_NAME = ''), 0) Возвращает 0. - person Kingsley Uyi Idehen; 09.11.2017