eq vs =
Thursday, 13 December 2018 · 4 messages
LS
Leo Studer13 Dec 2018 10:16 #
Hello
Could someone explain me why this woks
//country[@population = max(//@population)]/name
Whereas this does not
//country[@population eq max(//@population)]/name
Thanks in advance
Leo
CG
Christian Grün13 Dec 2018 10:46 #
Hi Leo,
The semantics of value comparisons (eq, ne, …) and general comparisons (=, !=, …) are different. As E. Wray indicated, sequences with more than one item can be compared with general comparisons; the result will always be a boolean (value comparisons will return an empty sequence if at least one value is an empty sequence).
In addition, values of document nodes (in your case, @population) will be cast to the type of the other value (in your case, a double, resulting from
fn:max). This implicit cast doesn’t take place if you use value comparisons, you’ll have to do this explicitly:
Does not work:
<x a='1'/>[@a eq 1]
Works:
<x a='1'/>[number(@a) eq 1]
This is why your second query yields an error. See Sections 3.7.1 and 3.7.2 of the XQuery spec for all the comprehensive details [1].
In practice, I would recommend you to always use the general comparison operator in BaseX, as it provides more optimizations. In many cases, if it’s safe, value comparisons will automatically be rewritten to general comparisons by the compiler.
Best,
Christian
[1] https://www.w3.org/TR/xquery-31/#id-value-comparisonsQuoted text · Leo Studer · 15 lines
On Thu, Dec 13, 2018 at 10:17 AM Leo Studer <leo.studer at varioweb.ch> wrote: > > Hello > > Could someone explain me why this woks > > //country[@population = max(//@population)]/name > > Whereas this does not > > //country[@population eq max(//@population)]/name > > > Thanks in advance > Leo
EJ
The value comparison operators (eq, lt, etc.) are designed for comparing single values (i.e. sequences of one value each). The general comparison operators (=, <, etc.) are designed for comparing sequences of more than one value.
E. Wray Johnson
Quoted text · Leo Studer · 15 lines
> On Dec 13, 2018, at 4:16 AM, Leo Studer <leo.studer at varioweb.ch> wrote: > > Hello > > Could someone explain me why this woks > > //country[@population = max(//@population)]/name > > Whereas this does not > > //country[@population eq max(//@population)]/name > > > Thanks in advance > Leo
LS
Thank you Christian and Wray
The implicit cast is the problem (as usual). I was expecting it to happen equally :(
And I teach my students to use value comparisons when ever possible and to care about the cast yourself ;-)
Yours
Leo
Quoted text · Christian Grün · 50 lines
> On 13 Dec 2018, at 10:46, Christian Grün <christian.gruen at gmail.com> wrote: > > Hi Leo, > > The semantics of value comparisons (eq, ne, …) and general comparisons > (=, !=, …) are different. As E. Wray indicated, sequences with more > than one item can be compared with general comparisons; the result > will always be a boolean (value comparisons will return an empty > sequence if at least one value is an empty sequence). > > In addition, values of document nodes (in your case, @population) will > be cast to the type of the other value (in your case, a double, > resulting from fn:max). This implicit cast doesn’t take place if you > use value comparisons, you’ll have to do this explicitly: > > Does not work: > <x a='1'/>[@a eq 1] > Works: > <x a='1'/>[number(@a) eq 1] > > This is why your second query yields an error. See Sections 3.7.1 and > 3.7.2 of the XQuery spec for all the comprehensive details [1]. > > In practice, I would recommend you to always use the general > comparison operator in BaseX, as it provides more optimizations. In > many cases, if it’s safe, value comparisons will automatically be > rewritten to general comparisons by the compiler. > > Best, > Christian > > [1] https://www.w3.org/TR/xquery-31/#id-value-comparisons > > > > On Thu, Dec 13, 2018 at 10:17 AM Leo Studer <leo.studer at varioweb.ch> wrote: >> >> Hello >> >> Could someone explain me why this woks >> >> //country[@population = max(//@population)]/name >> >> Whereas this does not >> >> //country[@population eq max(//@population)]/name >> >> >> Thanks in advance >> Leo
Written for BaseX 9.1. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery