eXist-db / exist

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

[BUG] Static base URI returned by static-base-uri() is not the URI of the entity and is not an absolute URI #4517

Open cmsmcq opened 2 years ago

cmsmcq commented 2 years ago

Describe the bug When an XQuery module evaluated within Oxygen calls the static-base-uri() function, the value returned ("/db") is not the URI of the query module and is not an absolute URI.

When the same module (or at least, as close to "the same" as cut and paste can manage) is evaluated within exide, no value is returned.

Expected behavior The expected behavior of static-base-uri() is to return the base URI in the static context. This is defined by XPath 3.1, sec. 2.1.1 as "an absolute URI, used to resolve relative URI references".

XQuery sec. 4.5 explains that the static base URI can be set by the user and that if not set by the user it defaults (to put it informally) to the location of the query module:

If no base URI declaration is present, Static Base URI property is established according to the principles outlined in [RFC3986] Section 5.1—that is, it defaults first to the base URI of the encapsulating entity, then to the URI used to retrieve the entity, and finally to an implementation-defined default.

To Reproduce In Oxygen, after setting things up as described in the eXist-db documentation, create an XQuery file with the following content:

xquery version "3.1";

<tests>
    <static-base-uri>{ static-base-uri() }</static-base-uri>
    <does-sbu-exist>{ exists(static-base-uri()) }</does-sbu-exist>
    <rel>{ resolve-uri('#foobar') }</rel>
    <rel>{ resolve-uri('#foobar', static-base-uri() ) }</rel>  
</tests>

On my system, this returns

<tests>
    <static-base-uri>/db</static-base-uri>
    <does-sbu-exist>true</does-sbu-exist>
    <rel>/db#foobar</rel>
    <rel>/db#foobar</rel>
</tests>

As a side note: in exide, this returns an error report:

<exception>
    <path>/db/tmp/uri-testing.xq</path>
    <message>
      err:FONS0005 base URI of the static context has not been assigned a value. [at line 7, column 12, source: /db/tmp/uri-testing.xq]
    </message>
</exception>

If the two rel elements are commented out, it returns

<tests>
    <static-base-uri/>
    <does-sbu-exist>false</does-sbu-exist>
    <!--
        <rel>{ resolve-uri('#foobar') }</rel>
        <rel>{ resolve-uri('#foobar', static-base-uri() ) }</rel>
    -->
</tests>

Discussion

There are several distinct problems in the current behavior:

N.B. It is not, strictly speaking, non-conforming for the static base URI property to be unset, or to be set to a value that is not the URI of the query module; both the XQuery spec and the relevant RFCs foresee the possibility of resources (here query modules) for which no URI is available. But all the relevant specs seem to be clear that this is an undesirable situation, and I think they make clear that a good-faith effort to identify the appropriate base URI is required for conformance. Since when running the query from exide, eXist clearly does have a path for the query and so can construct a URI for it, I think the failure to set the static base URI property is a bug. I don't know what information passes between Oxygen and eXist, so I do not know for a fact that in that case eXist has access to the URI for the query module -- but other query processors appear to have access to it, so I expect eXist can get access to it.

The failure to set the static base URI property properly is currently troubling me because it is making it harder for me to make a set of library modules work in eXist.

Context (please always complete the following information):

Additional context

joewiz commented 2 years ago

Hi Michael, when you say "create a file" could you provide more detail about the steps you're taking? Are you saving the file or running it in an unsaved state? If the former, are you saving it to disk or to the database?

cmsmcq commented 2 years ago

Hi Michael, when you say "create a file" could you provide more detail about the steps you're taking? Are you saving the file or running it in an unsaved state? If the former, are you saving it to disk or to the database?

Sure; sorry to have been vague.

  1. Launch Oxygen.
  2. Select File / New / XQuery. (In my case, at this point Oxygen shows a full file path for the unsaved file.)
  3. Write the query or paste in the text of the query.
  4. Evaluate the query with eXist (before saving). (In my case, the results are as described earlier.)
  5. Save to disk with a new file name.
  6. Evaluate again. (In my case, the result are again as described earlier. That is, on my system, saving made no difference. Both before and after saving, the Oxygen display showed a full file path. I was unable to create a new file for which Oxygen did not supply a path, but I did not try more than four or five times.)

I did not experiment with saving the query to the eXist database from Oxygen.

When I now use the Data Source Explorer in Oxygen to retrieve the version of the query I saved from exide in the eXist database, evaluating the query with eXist shows the static base URI as /db. (And, for comparison, evaluating it with Saxon PE shows it as oxygen:/eXist-db%20localhost$eXist-db%20localhost/db/tmp/uri-testing.xq).