Exist: [BUG] missing location info in errors for functions inside element constructors (err:XQTY0105)

Created on 6 Jul 2020  路  12Comments  路  Source: eXist-db/exist

Describe the bug

In eXist, errors involving functions inside element constructors like element foo { map { "x": "y" } } lack location information.

Expected behavior

I expected the errors to report the location of the error in the query, as they do in BaseX and Saxon. (Saxon has the best error description of the 3 in this case.)

To Reproduce

xquery version "3.1";

element foo { map { "x": "y" } }

eXist error:

err:XQTY0105 Enclosed expression contains function item

BaseX returns the error at the start of the enclosed content:

Stopped at /Users/joe/Downloads/file, 3/13:

[XQTY0105] Invalid content: map { "x": "y" }.

Saxon reports the error as appearing at the first character of the map constructor, with a very clear error description (if missing the error code):

Cannot add a map as a child of a constructed element

Start location: 3:16

Context (please always complete the following information):

  • OS: macOS 10.13.6
  • eXist-db version: 5.3.0-SNAPSHOT
  • Java Version: JDK 11.0.7+10 (Liberica 2020-04-14 LTS)

Additional context

  • How is eXist-db installed? 5.3.0-SNAPSHOT built from source
  • Any custom changes in e.g. conf.xml? None.
bug parser xquery

Most helpful comment

This one was a little bit harder to crack. Also, I think I got lucky because compConstructorValue did the main trick: adding location info to element content sub-expressions.

All 12 comments

Whilst digging around I cannot find any linear/column number in the hierarchy. I assume for now that #setLocation is not invoked for example from the AST. Help is appreciated

org.xmldb.api.base.XMLDBException: err:XQTY0105 Enclosed expression contains function item
    at org.exist.xmldb.LocalXPathQueryService.execute(LocalXPathQueryService.java:201)
    at org.exist.xmldb.LocalXPathQueryService.lambda$execute$2(LocalXPathQueryService.java:165)
    at org.exist.xmldb.function.LocalXmldbFunction.apply(LocalXmldbFunction.java:46)
    at org.exist.xmldb.AbstractLocal.withDb(AbstractLocal.java:263)
    at org.exist.xmldb.LocalXPathQueryService.execute(LocalXPathQueryService.java:164)
    at org.exist.client.QueryDialog$QueryRunnable.run(QueryDialog.java:587)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.exist.xquery.XPathException: err:XQTY0105 Enclosed expression contains function item
    at org.exist.xquery.EnclosedExpr.eval(EnclosedExpr.java:101)
    at org.exist.xquery.ElementConstructor.eval(ElementConstructor.java:330)
    at org.exist.xquery.AbstractExpression.eval(AbstractExpression.java:71)
    at org.exist.xquery.PathExpr.eval(PathExpr.java:281)
    at org.exist.xquery.AbstractExpression.eval(AbstractExpression.java:71)
    at org.exist.xquery.XQuery.execute(XQuery.java:261)
    at org.exist.xquery.XQuery.execute(XQuery.java:185)
    at org.exist.xmldb.LocalXPathQueryService.execute(LocalXPathQueryService.java:198)
    ... 6 more

interestingly the query

xquery version "3.1";

let $a := 1

return
element foo { map { "x": "y" } }

results in

An exception occurred during query execution: err:XQTY0105 Enclosed expression contains function item [at line 3, column 6]

making the original query actually report on location (0,0) (where unknown location is internally -1,-1)

the path variable passed to org.exist.xquery.parser.XQueryTreeParser#constructor seem to contain the correct value; just a bit later the value is not in the expression.

I give up, I hope @wolfgangmm or @ljo can have a look

The current develop branch (eXist 5.3.0-SNAPSHOT e92ea8f70512dd6dbb49bc1fc059f64944bee045 20200915110349) is still affected.

This is issue is likely related to #3518 - the XQueryParser swallows the location information by introducing a virtual AST node.

This one was a little bit harder to crack. Also, I think I got lucky because compConstructorValue did the main trick: adding location info to element content sub-expressions.

The simple case works has location and throws at compile time.
A slightly modified - and more realistic scenario - still throws without location information. 鈽癸笍

element a { 
  attribute href { "#" },
  map {} (: a function item added to element content by mistake :)
}

This way of writing it is also missing location info.

element a { 
  (
    attribute href { "#" },
    map {} (: a function item added to element content by mistake :)
  )
}

Interestingly location information is available for this case:

element a { [map {}] }

There is also this edge case:

element a { ("", map {})[1] }, (: this is fine :)
element a { (map {})[2] }, (: this throws - in Saxon10-HE as well - but could actually evaluate to <a /> :)

And there is more to think about. Compare the location reported by these two queries:

let $a := map {} return element a { $a }
(: err:XQTY0105 Enclosed expression contains function item [at line 1, column 38, ...] :)
let $a := map {} return element a { "", $a }
(: err:XQTY0105 Enclosed expression contains function item [at line 1, column 6, ...] :)

sub-expression location seems to be broken somewhat.

These two report the function item to be at line 1, column 6 as well

let $a := map {} return element a { ($a) }
let $a := map {} return element a { ("", $a) }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

opax picture opax  路  3Comments

mathias-goebel picture mathias-goebel  路  4Comments

Bpolitycki picture Bpolitycki  路  4Comments

lguariento picture lguariento  路  5Comments

dizzzz picture dizzzz  路  5Comments