eXist-db / exist

eXist Native XML Database and Application Platform
https://exist-db.org
GNU Lesser General Public License v2.1
422 stars 179 forks source link

"name is empty" error with valid ft:query #3444

Open moritzschepp opened 4 years ago

moritzschepp commented 4 years ago

A certain index definition in collection.xconf leads to a "name is empty" exception. I have not found a way to recover from the error: Once it occurs, also the on-board documentation search throws the same error. To reproduce:

Run a fresh eXist-db with docker:

docker run -it --rm -p 8080:8080 -p 8443:8443 --name exist existdb/existdb:latest

This is the image digest:

81915347a82d2e4b621e7aa1b5c490dcd65bb1efe05931f907e17b4479e5f959

Install the attached myapp-0.01.xar, open the contained collection.xconf and save it. The system asks to apply it to the collection, do it. Then eval the included query.xq.

I can reproduce the problem within the docker image and within a Debian 10 VM (no docker).

Am I using the index definitions right? Can I avoid this error somehow?

Its worth noting that eXide shows me errors for the collection.xconf but it also shows those for exact copy&paste from the indexing docs.

Let me know if I can provide more information.

myapp-0.1.zip (github didn't like the xar, wrapped it in a zip)

Oh, almost forgot: This is the only other issue I found that mentions something similar: #1353

joewiz commented 4 years ago

@moritzschepp Could you paste in the full exception?

joewiz commented 4 years ago

@moritzschepp Two suggestions:

  1. Your collection.xconf defines a Lucene field on <tei:person> elements with the value of the expression *[@xml:lang='de']. Therefore, the contents of the field will be the concatenated text nodes of all direct child elements tagged as being in German. Is that what you intend?

  2. Your query.xq uses the ft:query function in a non-standard way. Typically, you use it inside a predicate, e.g.:

let $base := doc('/db/apps/myapp/data.xml')//tei:person
let $hits := $base[ft:query(., 'de:a*')]
return $hits

Could you try this variant and let us know if this produces your expected results or, if not, what you're expecting?

joewiz commented 4 years ago

@moritzschepp Regarding the errors in eXide, this is because the schema eXide has for validating xconf files hasn't been updated to handle facets & fields. I've registered an issue in eXide for this and will submit a PR soon: https://github.com/eXist-db/eXide/issues/257.

moritzschepp commented 4 years ago

@joewiz, thanks for looking into this!

I didn't see that eXide logs more than "name is empty". I attached the docker output, let me know if this is not what you meant.

Yes, the field definition was intended as you describe.

I changed the query as you suggested. The error is the same, though.

collection.xconf schema: That's good to know, I suspected something like that. I'll watch out for that pull request.

joewiz commented 3 years ago

@moritzschepp Please see https://github.com/eXist-db/eXide/pull/279. This fixes the errors that eXide would raise when validating an .xconf file containing facet or field definitions. When you have the chance, if you could confirm that this PR fixes all aspects of your issue, please close this - or if there was some other aspect to your issue that remains unsolved, please note what remains? Thanks.

moritzschepp commented 3 years ago

Thanks for getting back to this issue, @joewiz!

This issue is about a problem with the indexing functionality itself: When the error occurs, indexing is broken within the entire eXist-db instance, including documentation search. The problem is reproducible, see issue description above.

eXist-db/eXide#279 only deals with exide error reporting, right?

joewiz commented 3 years ago

@moritzschepp Ah, I see! To workaround the name is empty error, try changing your query to perform the ft:query predicate in the same expression as selecting the person nodes. In other words, change query.xq to:

xquery version "3.1";

declare namespace tei="http://www.tei-c.org/ns/1.0";

let $hits := doc('/db/apps/myapp/data.xml')//tei:person[ft:query(., 'de:a*')]
return $hits

I don't see anything in eXist's Lucene documentation that would suggest your original formulation should fail, much less with a vague name is empty error lacking location. Thus, let's keep the issue open and label it as a confirmed bug.

Here's the portion of exist.log that is generated when using your original query:

2020-11-30 13:09:53,334 [qtp1336471966-76] ERROR (XQueryServlet.java [process]:558) - name is empty 
java.lang.IllegalArgumentException: name is empty
    at org.exist.dom.persistent.SymbolTable.getSymbol(SymbolTable.java:202) ~[exist-core-5.3.0-SNAPSHOT.jar:5.3.0-SNAPSHOT]
    at org.exist.indexing.lucene.LuceneUtil.encodeQName(LuceneUtil.java:90) ~[exist-index-lucene-5.3.0-SNAPSHOT.jar:5.3.0-SNAPSHOT]
    at org.exist.indexing.lucene.LuceneIndexWorker.lambda$query$0(LuceneIndexWorker.java:437) ~[exist-index-lucene-5.3.0-SNAPSHOT.jar:5.3.0-SNAPSHOT]
    at org.exist.indexing.lucene.LuceneIndex.withSearcher(LuceneIndex.java:259) ~[exist-index-lucene-5.3.0-SNAPSHOT.jar:5.3.0-SNAPSHOT]
    at org.exist.indexing.lucene.LuceneIndexWorker.query(LuceneIndexWorker.java:432) ~[exist-index-lucene-5.3.0-SNAPSHOT.jar:5.3.0-SNAPSHOT]
    at org.exist.xquery.modules.lucene.Query.eval(Query.java:269) ~[exist-index-lucene-5.3.0-SNAPSHOT.jar:5.3.0-SNAPSHOT]
    at org.exist.xquery.InternalFunctionCall.eval(InternalFunctionCall.java:62) ~[exist-core-5.3.0-SNAPSHOT.jar:5.3.0-SNAPSHOT]

To confirm, your original query that produces this error is:

xquery version "3.1";

declare namespace tei="http://www.tei-c.org/ns/1.0";

let $base := doc('/db/apps/myapp/data.xml')//tei:person
let $hits := $base[ft:query(., 'de:a*')]
return $hits
joewiz commented 3 years ago

p.s. I can also confirm that when your myapp is installed, searching the documentation app, e.g., via http://localhost:8080/exist/apps/doc/search.html?q=help, fails with a name is empty error. Deleting your myapp via the package manager resolves the issue. But it's strange that a perfectly valid collection.xconf in one file can affect queries in another collection entirely.

moritzschepp commented 3 years ago

@moritzschepp Ah, I see! To workaround the name is empty error, try changing your query to perform the ft:query predicate in the same expression as selecting the person nodes. In other words, change query.xq to:

xquery version "3.1";

declare namespace tei="http://www.tei-c.org/ns/1.0";

let $hits := doc('/db/apps/myapp/data.xml')//tei:person[ft:query(., 'de:a*')]
return $hits

This seems to be what you suggested in https://github.com/eXist-db/exist/issues/3444#issuecomment-640903654. I tried that but it's not a workaround, unfortunately.