Peculiar External Binding and Casting Behaviour

Monday, 30 October 2017 · 3 messages · last reply 31 Oct 2017
SF
Shaun Flynn30 Oct 2017 10:38 #
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
CG
Christian Grün30 Oct 2017 10:57 #
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
SF
Shaun Flynn31 Oct 2017 07:21 #
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 >>> >> > >>> >> > >>> > >>> > >>> >> >>

⚡Generated with XQuery