Peculiar External Binding and Casting Behaviour
Hello there,
I am having issues with the following query:
declare default element namespace "http://www.tracsis.com/TTVP_Interface";
declare variable $date := "2017-07-10";
declare variable $daysRun := 3;
declare variable $diagrams :=
diagramExchange/unitDiagramList/unitDiagram[@startdate<=$date][@enddate>=$date][substring(@daysrun,$daysRun,1)="Y"];
*declare variable $depotConstraint external;*
*declare variable $resConstraint external;*
*declare variable $lowerDiagNoConstraint external;*
*declare variable $upperDiagNoConstraint external;*
*declare variable $depots := tokenize($depotConstraint," ");*
*declare variable $resources := tokenize($resConstraint," ");*
*declare variable $lowerDiagNo := tokenize($lowerDiagNoConstraint," ");*
*declare variable $upperDiagNo := tokenize($upperDiagNoConstraint," ");*
declare function local:begin($diagrams, $index) {
local:applyDiagStartFilter($diagrams,$index)
};(: Chain of responsibility pattern used here : once one function exits, passes to the next:)
declare function local:applyDiagStartFilter($diagrams, $index) {
let $diagNo := $lowerDiagNo[$index]
return
if($diagNo = "NIL") then
(local:applyDiagEndFilter($diagrams, $index))
else
*(local:applyDiagEndFilter($diagrams[@id >= $diagNo cast as xs:integer]*,
$index))
};
declare function local:applyDiagEndFilter($diagrams, $index) {
let $diagNo := $upperDiagNo[$index]
return
if($diagNo= "NIL") then
(local:applyResFilter($diagrams, $index))
else
(local:applyResFilter($diagrams[@id <= $diagNo cast as xs:integer],
$index))
};
declare function local:applyResFilter($diagrams, $index) {
let $res := $resources[$index]
return
if($res = "NIL")
then
(local:applyDepotFilter($diagrams, $index))
else
(local:applyDepotFilter($diagrams[res/@id = $res], $index))
};
declare function local:applyDepotFilter($diagrams, $index) {
let $depot := $depots[$index]
return
if($depot = "NIL")
then
($diagrams)
else
($diagrams[depot/@id = $depot])
};
for $depot in $depots
count $count
return local:begin($diagrams, $count)The underlined sections are the ones giving an issue.
When I set the following like so:
*declare variable $depotConstraint := "PM OC";*
*declare variable $resConstraint := "NIL 180/1";*
*declare variable $lowerDiagNoConstraint := "NIL NIL";*
*declare variable $upperDiagNoConstraint := "NIL NIL";*The query runs fine.
When I try and set these externally, I get error "FORG0001 : Cannot cast to xs:double" at the following underlined location:
declare function local:applyDiagStartFilter($diagrams, $index) {
let $diagNo := $lowerDiagNo[$index]
return
if($diagNo = "NIL") then
(local:applyDiagEndFilter($diagrams, $index))
else
*(local:applyDiagEndFilter($diagrams[@id >= $diagNo cast as xs:integer]*,
$index))
};I do not understand why that should be as there is clearly no mention of xs:double in this query! Also, this happens when $diagNo is "NIL" which is even more perplexing as that would suggest it fails the "if" test somehow.
The $xxxxConstraint variables are all supplied as strings.
What am I doing wrong?
I am using BaseX 8.6.7 in Java 8.
Shaun
HiShaun,
Quoted text · Shaun Flynn · 2 lines
> I do not understand why that should be as there is clearly no mention of > xs:double in this query!
I agree that the error message is misleading. You already get it when invoking the following expression:
'a' cast as xs:integer
I need to check the code, but I assume that an additional double conversion check takes place in the background in order to ensure that the value can actually be converted to a non-fractional number.
For more information on your query, it would be great if you could reduce it to a self-contained example that runs out of the box (I tried to invoke it, but your code seems to rely on an opened database).
Best, Christian
Hello there,
I found the problem! My code added a trailing space to the values of the variables when binding.
After tokenizing in the XQuery, this creates a zero length string which when cast to xs:integer then becomes an xs:double according to the error message.
Is this intended behaviour?
Shaun
Quoted text · Shaun Flynn · 115 lines
On 31 Oct 2017 06:20, "Shaun Flynn" <scfy12 at googlemail.com> wrote: > Hello there, > > I found the problem! My code added a trailing space to the values of the > variables when binding. > > After tokenizing in the XQuery, this creates a zero length string which > when cast to xs:integer then becomes an xs:double according to the error > message. > > Is this intended behaviour? > > Shaun > > On 30 Oct 2017 17:39, "Shaun Flynn" <scfy12 at googlemail.com> wrote: > >> Hello there, >> >> I created a simple example using the BaseX Java API, and that worked >> fine, also using my code to create the query and submit it to a >> ClientSession worked ok too :( >> >> This was the query I ran: >> >> declare variable $items external := "123 NIL"; >> declare variable $tokenizedItems:= tokenize($items," "); >> >> for $item in $tokenizedItems >> return >> if($item = "NIL") then ("Nil") else (xs:integer($item)) >> >> Unable to reproduce the earlier result from today using my code as well :( >> >> So I can understand the error better: "[FORG0001] Cannot cast to >> xs:double: ." >> >> The full stop after xs:double , does that relate to a decimal point or >> the current item (xquery .) >> >> Shaun >> >> On 30 October 2017 at 10:31, Christian Grün <christian.gruen at gmail.com> >> wrote: >> >>> Thanks. Some few lines of Java Code might already be sufficient >>> (provided that the problem can be reproduced with the XQuery snippet >>> that you sent in your last mail). >>> >>> On Mon, Oct 30, 2017 at 11:24 AM, Shaun Flynn <scfy12 at googlemail.com> >>> wrote: >>> > Hello there, >>> > >>> > I will put something together for you later on today in a .zip file. >>> > >>> > Shaun >>> > >>> > On 30 October 2017 at 10:22, Christian Grün <christian.gruen at gmail.com >>> > >>> > wrote: >>> >> >>> >> > However, when I bind variables externally in Java, still getting the >>> >> > same >>> >> > problem, and I definitely not putting quotes around them there. >>> >> >>> >> Do you have an example that might help me to reproduce it? >>> >> >>> >> >>> >> > $depotConstraint: PM >>> >> > $resourceConstraint: 143/6 >>> >> > $lowerDiagConstraint: 251 >>> >> > $upperDiagConstraint: 258 >>> >> > Oct 30, 2017 9:05:33 AM units.forms.UnitDiagramsController >>> >> > fetchSelectedDiagrams >>> >> > SEVERE: null >>> >> > org.basex.core.BaseXException: Stopped at ., 29/61: >>> >> > [FORG0001] Cannot cast to xs:double: . >>> >> > >>> >> > >>> >> > >>> >> > On 30 October 2017 at 09:57, Christian Grün < >>> christian.gruen at gmail.com> >>> >> > wrote: >>> >> >> >>> >> >> HiShaun, >>> >> >> >>> >> >> > I do not understand why that should be as there is clearly no >>> mention >>> >> >> > of >>> >> >> > xs:double in this query! >>> >> >> >>> >> >> I agree that the error message is misleading. You already get it >>> when >>> >> >> invoking the following expression: >>> >> >> >>> >> >> 'a' cast as xs:integer >>> >> >> >>> >> >> I need to check the code, but I assume that an additional double >>> >> >> conversion check takes place in the background in order to ensure >>> that >>> >> >> the value can actually be converted to a non-fractional number. >>> >> >> >>> >> >> For more information on your query, it would be great if you could >>> >> >> reduce it to a self-contained example that runs out of the box (I >>> >> >> tried to invoke it, but your code seems to rely on an opened >>> >> >> database). >>> >> >> >>> >> >> Best, >>> >> >> Christian >>> >> > >>> >> > >>> > >>> > >>> >> >>
Written for BaseX 8.6. BaseX may have changed since: please check the current documentation.