ligasgr / intellij-xquery

Plugin to support XQuery in Intellij Idea
Apache License 2.0
35 stars 23 forks source link

name function, etc. flagged as error but fn:name is not in modules #146

Open rhdunn opened 8 years ago

rhdunn commented 8 years ago

Given:

xquery version "3.0";
module namespace foo = 'http://marklogic.com/ns/foo';
declare function bar($foo) {
    name($foo)
};

The name call is flagged with the error Cannot resolve function 'name', but fn:name is resolved correctly. Also, removing the module declaration, i.e.:

xquery version "3.0";
declare function bar($foo) {
    name($foo)
};
()

removes the error message (name is resolved correctly).

The same applies to other functions that are in the global namespace (exists, etc.).

ligasgr commented 8 years ago

Hi, this is define in Library Modules Default Function Namespace Defaults to Library Namespace in official MarkLogic documentation. The default namespace in the module if you are using MarkLogic is the module namespace. The function will get resolved correctly if you add "fn:" prefix to it or you switch the flavour in Setting->Other Settings->XQuery->Other options->XQuery flavour to "XQuery 3.0 Standard". This was part of the issue https://github.com/ligasgr/intellij-xquery/issues/80

ligasgr commented 8 years ago

I don't have MarkLogic 8 instance working available. Would you be able to confirm if code like that if when run works ok? If yes then either MarkLogic misbehaves or they should update their documentation.

rhdunn commented 8 years ago

The above definitely works in library modules on at least MarkLogic 7 and 8 (string, name, format-date, etc.). NOTE: I am seeing those being flagged as errors even using the "XQuery 3.0 Standard" syntax setting.

According to that documentation:

"The default function namespace of an XQuery library module is the namespace of the library module. This allows you to declare functions in the library namespace without prefixing the functions. You can override the default function namespace with a declare default function namespace declaration in the prolog of the library module."

This means that when you do:

module namespace foo = 'http://marklogic.com/ns/foo';
declare function bar($foo)

bar is automatically placed in the foo namespace, without you having to explicitly prefix it as foo:bar. This is different to non-library scripts where functions need an explicit namespace declaration (with local: as an allowed prefix).

"For library modules where you do not override the default function namespace (and as a general best-practice), you should prefix the XQuery-standard functions (functions with the fn: prefix, which is bound to the http://www.w3.org/2005/xpath-functions namespace) with the fn: prefix."

This says that you should prefix standard functions in library modules with fn:, not that you must prefix them. IIUC, this is to avoid a library function with the same name as a standard function overriding the behaviour where the calls are expected to be to the standard functions.

"Note that main modules default function namespace defaults to the fn: namespace, which is different from library modules."

This means that libraries default to the module namespace specified, while main modules default to the fn: namespace. This is why declare function bar does not work for main modules, as that would place bar in fn:bar.

rhdunn commented 8 years ago

There is a thread at http://developer.marklogic.com/pipermail/general/2014-July/015373.html that suggests that erroring on unprefixed fn: calls is MarkLogic 6 behaviour, with some cases of it in MarkLogic 7. I haven't encountered it in the version of MarkLogic 7 I am using, so it is likely that those cases on MarkLogic 7 were bugs that have been fixed.

According to a comment in http://stackoverflow.com/questions/19529920/drop-the-fn-in-marklogic-functions:

"There's a feature coming in V7 that will allow you to specify a set of default namespaces for a given application server and I believe the default set now includes fn." – Eric Bloch

ligasgr commented 8 years ago

Hey,

Thanks for digging a bit deeper around it. This feature (in Marklogic) is undocumented and well outside of scope of what the XQuery 3.0 spec writes about default function namespace. I'll see if it will be possible to make it work properly with the functionality as you described it. And I'll definitely raise this somewhere in MarkLogic.