This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 5915 - [FS] rules for XPST0005
Summary: [FS] rules for XPST0005
Status: CLOSED INVALID
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: Formal Semantics 1.0 (show other bugs)
Version: Recommendation
Hardware: PC Windows NT
: P2 normal
Target Milestone: ---
Assignee: Michael Dyck
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-07-30 15:45 UTC by Tim Mills
Modified: 2008-11-12 12:09 UTC (History)
1 user (show)

See Also:


Attachments

Description Tim Mills 2008-07-30 15:45:44 UTC
The text in section 4 of FS states:

During static analysis, it is a type error for an expression to have the empty type, except for the following expressions and function calls:

    * Empty parentheses (), which denote the empty sequence.
    * The fn:data function and all functions in the fs namespace applied to empty parentheses ().
    * Any function which returns the empty type.

Consider the query:

1 + ()

This normalizes to:

fs:plus(fs:convert-operand(data(1), 1), 
        fs:convert-operand(data(()), 1)))

Although the arguments to fs:plus as written include (), in the normalized form this is not the case.  However, I suspect that the intention of these rules was to allow this query to pass without error.  

Following the above rules, data( () ) does not trigger an error, but has the static type 'empty'.

In fs:convert-operand(data(()), 1), fs:convert-operand triggers an XPST005 error because it is being applied to data( () ) and not to ().

Could you please clarify?
Comment 1 Michael Dyck 2008-07-31 02:28:19 UTC
> In fs:convert-operand(data(()), 1), fs:convert-operand triggers an XPST005
> error because it is being applied to data( () ) and not to ().

I think you're assuming that the static type of
    fs:convert-operand(data(()), 1)
is the empty type, but I don't think it is. With respect to FS 7.1.1 / STA,
Type1 is empty and Type2 is xs:integer. Since
    empty <: xs:untypedAtomic ?
and
    xs:integer <: fs:numeric,
I believe rule 3 holds, and we infer a type of xs:double?.
(Mind you, that might be an unintended result.)
Comment 2 Tim Mills 2008-07-31 07:54:37 UTC
We have a type rule based on the description of fs:convert-operand in 7.1.1 The fs:convert-operand function:

If $actual is the empty sequence, returns the empty sequence.

In fact, we actually borrow the rules in C.2 Mapping of Overloaded Internal Functions, because they cover the case of union types.  Consider

U = (T1 | T2)
T1 <: xs:untypedAtomic?
not(T2 <: xs:untypedAtomic?)

Following the static typing rules in 7.1.1:

statEnv  |-  not(U <: xs:untypedAtomic?)
-------------------------------------------------------------
statEnv |-  (FS-URI,"convert-operand")( U, Type2) : U

This is clearly wrong.

It seems unfortunate that introducing a rule to improve the precision of a static typing judgement leads us to fall foul of another area of the specification.

Is there a good reason why the rule:

    * The fn:data function and all functions in the fs namespace applied to
empty parentheses ().

is not stated as:

    * The fn:data function and all functions in the fs namespace whose statoc return types can be determined to be the empty type.


Comment 3 Tim Mills 2008-07-31 08:21:44 UTC
Correct me if I'm wrong but I think that the following fs:* functions can never be directly applied to ():

fs:convert-operand
fs:distinct-doc-order
fs:distinct-doc-order-or-atomic-sequence 
fs:apply-ordering-mode
fs:attribute-content-sequence
fs:eq etc. (value comparisons)
fs:is etc. (node comparisons)
fs:plus etc. (arithmetic operators)
fs:to

The following can be directly applied to ().

fs:item-sequence-to-string-attr
fs:item-sequence-to-node-sequence 
fs:item-sequence-to-untypedAtomic-PI 
fs:item-sequence-to-untypedAtomic-text
fs:item-sequence-to-untypedAtomic-comment
fs:convert-simple-operand

I hope this list is exhaustive!

The fs:to functio
fs:eq (etc.)
fs:plus (etc.)


Comment 4 Tim Mills 2008-07-31 08:30:08 UTC
I missing of fs:item-at which can never be applied directly to ().
Comment 5 Tim Mills 2008-07-31 08:38:01 UTC
(In reply to comment #1)
> > In fs:convert-operand(data(()), 1), fs:convert-operand triggers an XPST005
> > error because it is being applied to data( () ) and not to ().
> 
> I think you're assuming that the static type of
>     fs:convert-operand(data(()), 1)
> is the empty type, but I don't think it is. With respect to FS 7.1.1 / STA,
> Type1 is empty and Type2 is xs:integer. Since
>     empty <: xs:untypedAtomic ?
> and
>     xs:integer <: fs:numeric,
> I believe rule 3 holds, and we infer a type of xs:double?.
> (Mind you, that might be an unintended result.)
> 

Sorry to keep on rambling on here, but doesn't this mean that the rules in C.2 Mapping of Overloaded Internal Functions:

Type1 = empty
-----------------------------------------------
statEnv |-  expanded-QName(Type1,Type2) : empty

Type2 = empty
-----------------------------------------------
statEnv |-  expanded-QName(Type1,Type2) : empty

can never be applied, because the introduction of fs:convert-operand?

I can't believe that FS as it stands can't determine that 1 + () has the empty type!
Comment 6 Michael Dyck 2008-10-09 09:44:14 UTC
(In reply to comment #2)
> Consider
> 
> U = (T1 | T2)
> T1 <: xs:untypedAtomic?
> not(T2 <: xs:untypedAtomic?)
> 
> Following the static typing rules in 7.1.1:
> 
> statEnv  |-  not(U <: xs:untypedAtomic?)
> -------------------------------------------------------------
> statEnv |-  (FS-URI,"convert-operand")( U, Type2) : U
> 
> This is clearly wrong.

I agree with your analysis, and agree that the result is unsound. I will
propose some replacement rules to fix this. 

The new rules will probably change the static type of
    fs:convert-operand(data(()), 1)
to 'empty', which gets us back to your original point, namely:
-- since it has a static type of 'empty', it's subject to the rule in
   section 4, and
-- since it doesn't qualify as an exception, it must raise an error,
-- which you suspect is unintended.

I'm not sure it's unintended. Looking at the XQuery/XPath spec, it seems
clear from the wording in 2.3.1 that the expression
    1 + ()
should raise an error if the processor supports the Static Typing Feature.
And, back in FS-land,
    fs:convert-operand(data(()), 1)
will raise an error, thus agreeing with the XQuery/XPath spec.

It would be more interesting if there were an example expression where the
two specs *didn't* agree on whether XPST0005 should be raised.
Comment 7 Michael Dyck 2008-10-13 21:21:10 UTC
Regarding the unsound static typing rules for fs:convert-operand,
I've pulled that problem out as a separate bug: Bug 6160.
Comment 8 Michael Dyck 2008-11-11 07:44:02 UTC
Now that Bug 6160 is resolved, let's return to your original comment.

Given the query 1+(), we agree that the FS rules (applied to the normalized
query) raise an error. "However," you say, "I suspect that the intention of
these rules was to allow this query to pass without error."  My response is
that, regardless of their intention, their effect (raising an error) agrees
with the requirements of the XQuery/XPath language spec, and therefore this
example does not constitute a bug. On 2008-10-27, the XQuery WG agreed, and
directed me to mark this issue as resolved-invalid.  If you agree with this
resolution, please mark the issue closed.

This is not to assert that the two specs are always in agreement re raising
XPST0005, rather that if valid examples of disagreement are found, they
should go in another bug report.
Comment 9 Tim Mills 2008-11-12 12:09:16 UTC
I think that clears everything up.  Thanks.