Re: [basex-talk] Uncomprehensible (at least to me) behaviour with external bindings

2018-03-21 Thread Christian Grün
Hi Marco,

With the latest snapshot, the BINDINGS options will not be considered
anymore when using xquery:eval (or with any other query sub process).

With regards to the general solution of binding external variables, it
would be a bit more time consuming to realize a working solution: When
external variables are initially registered in BaseX (via BINDINGS,
via APIs, via REST, …), it is not clear yet if there will be any
variable declarations for it in the query prolog. So all non-XQuery
values will be cast to a specified target type, or (if none is
specified) a type that results from the standard Java type bindings
[1]. It would probably be better if non-XQuery values were only bound
at compile time (we could then avoid converting a Java String as
xs:string if the actual variable type is a number).

As indicated, maybe it already helps you if you switch to xs:integer.
If you bind values via Java, you can additionally specify the XQuery
target type [2,3].

Cheers,
Christian

[1] http://docs.basex.org/wiki/Java_Bindings#Data_Types
[2] 
https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/core/cmd/XQuery.java#L35-L45
[3] 
https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/query/QueryProcessor.java#L115-L131




On Wed, Mar 21, 2018 at 4:57 PM, Christian Grün
 wrote:
> Hi Marco,
>
> Working with external variables can be tricky, and it’s difficult to
> explain all the intricate implications. But let’s try ;) First of all,
> I noticed the error messages differed in my tests, so please note I
> have used the latest snapshot (BaseX 9.0 RC4) for testing:
>
>
>> trying to understand why we get the exception [2] running the code [1] in a
>> Java app
>
> Could you possibly forward us the Java code as well?
>
>> xquery:eval("
>> declare variable $_dep as xs:long* external;
>> $_dep[2] * $_dep[2]", map{ "_dep" : (1,2,3)})
>>
>> obtaining the correct result (4).
>
> This currently works, because external variables will first be cast to
> the target type. Ideally it should give you an exception, because the
> input is of type xs:integer, while it should be of type xs:long. For
> example, it’s correct that the following query gives you a type
> exception:
>
>   declare variable $v as xs:long := 1;
>   $v
>
> The following query is correct:
>
>   declare variable $v as xs:integer := 1;
>   $v
>
> I recommend you to use xs:integer whenever possible, because it’s the
> default XQuery type for integers (and BaseX internally uses long
> values for representing xs:integer anyway).
>
> However, back to your example: xquery:eval currently raises no
> exception because we are currently using the same code for binding
> variables as we do for external clients – and the latter one is more
> liberal (because the client may not be written in XQuery, and may thus
> have different data types).
>
>
>> Anyway if I assign (1,2,3) to a binding through the proper dialog of the UI
>> I get the following exception at execution:
>>
>> Error:
>> Stopped at
>> /home/lettere/git/dasbox-frontend/dasbox-frontend-ui/webapp/ui/resources/js/monitoring/file,
>> 2/12:
>> [FORG0001] Cannot cast to xs:double: (1,2,3).
>
> The reason here is that, right now, you can only bind single values
> via the bindings dialog…
>
>
>> Strangely enough this happens even if I leave the map overriding locally the
>> values for the external parameters in the xquery:eval. The dialog wins?
>
> …which will be bound to the global BINDINGS option [1]. Value
> assignments bound to this option will always override the values of
> external variable declarations. Maybe we should temporarily disable
> the values of this option while running a query, because I agree it
> makes no sense to have them bound within a nested xquery:eval call.
>
> Ideally, I would like to see the BINDINGS options removed one day,
> because most global options are prone to side effects – especially in
> combination with runtime evaluation based on things like xquery:eval.
> On the other hand, various APIs would probably need to be extended.
>
> Hope this helps. I’ll be happy to look at your Java code, and I’ll
> have some more thoughts on how we can make BaseX stricter without
> restricting external clients.
>
> Christian
>
> [1] http://docs.basex.org/wiki/Options#BINDINGS


Re: [basex-talk] Uncomprehensible (at least to me) behaviour with external bindings

2018-03-21 Thread Christian Grün
Hi Marco,

Working with external variables can be tricky, and it’s difficult to
explain all the intricate implications. But let’s try ;) First of all,
I noticed the error messages differed in my tests, so please note I
have used the latest snapshot (BaseX 9.0 RC4) for testing:


> trying to understand why we get the exception [2] running the code [1] in a
> Java app

Could you possibly forward us the Java code as well?

> xquery:eval("
> declare variable $_dep as xs:long* external;
> $_dep[2] * $_dep[2]", map{ "_dep" : (1,2,3)})
>
> obtaining the correct result (4).

This currently works, because external variables will first be cast to
the target type. Ideally it should give you an exception, because the
input is of type xs:integer, while it should be of type xs:long. For
example, it’s correct that the following query gives you a type
exception:

  declare variable $v as xs:long := 1;
  $v

The following query is correct:

  declare variable $v as xs:integer := 1;
  $v

I recommend you to use xs:integer whenever possible, because it’s the
default XQuery type for integers (and BaseX internally uses long
values for representing xs:integer anyway).

However, back to your example: xquery:eval currently raises no
exception because we are currently using the same code for binding
variables as we do for external clients – and the latter one is more
liberal (because the client may not be written in XQuery, and may thus
have different data types).


> Anyway if I assign (1,2,3) to a binding through the proper dialog of the UI
> I get the following exception at execution:
>
> Error:
> Stopped at
> /home/lettere/git/dasbox-frontend/dasbox-frontend-ui/webapp/ui/resources/js/monitoring/file,
> 2/12:
> [FORG0001] Cannot cast to xs:double: (1,2,3).

The reason here is that, right now, you can only bind single values
via the bindings dialog…


> Strangely enough this happens even if I leave the map overriding locally the
> values for the external parameters in the xquery:eval. The dialog wins?

…which will be bound to the global BINDINGS option [1]. Value
assignments bound to this option will always override the values of
external variable declarations. Maybe we should temporarily disable
the values of this option while running a query, because I agree it
makes no sense to have them bound within a nested xquery:eval call.

Ideally, I would like to see the BINDINGS options removed one day,
because most global options are prone to side effects – especially in
combination with runtime evaluation based on things like xquery:eval.
On the other hand, various APIs would probably need to be extended.

Hope this helps. I’ll be happy to look at your Java code, and I’ll
have some more thoughts on how we can make BaseX stricter without
restricting external clients.

Christian

[1] http://docs.basex.org/wiki/Options#BINDINGS


[basex-talk] Uncomprehensible (at least to me) behaviour with external bindings

2018-03-21 Thread Marco Lettere

Hi all,

trying to understand why we get the exception [2] running the code [1] 
in a Java app, I stumbled upon a strange behaviour of the GUI.


I rewrote the query to:

xquery:eval("
declare variable $_dep as xs:long* external;
$_dep[2] * $_dep[2]", map{ "_dep" : (1,2,3)})

obtaining the correct result (4).

Anyway if I assign (1,2,3) to a binding through the proper dialog of the 
UI I get the following exception at execution:


Error:
Stopped at 
/home/lettere/git/dasbox-frontend/dasbox-frontend-ui/webapp/ui/resources/js/monitoring/file, 
2/12:

[FORG0001] Cannot cast to xs:double: (1,2,3).

Strangely enough this happens even if I leave the map overriding locally 
the values for the external parameters in the xquery:eval. The dialog wins?


If I rewrite the query like this and remove the parameter values from 
the dialog:


xquery:eval("
declare variable $_dep as xs:long* external := (1,2,3);

$_dep[2] * $_dep[2]")

I get yet another typecast exception:

Error:
Stopped at 
/home/lettere/git/dasbox-frontend/dasbox-frontend-ui/webapp/ui/resources/js/monitoring/file, 
2/12:

[XPTY0004] Cannot promote xs:integer+ to $_dep as xs:long*: (1, 2, 3).

Is there a nice wording to explain all this different behaviour and 
might it be that the exception we get in the Java embedded version is 
somehow related to the same?


Thanks a lot for helping,

Marco.

[1]

declare variable $_history as xs:long* external;
declare variable $_now as xs:dateTime external;
declare variable $_dep as xs:long* external;
declare variable $dep as xs:long external;

$_dep[2] * $_dep[2]

[2]

Caused by: org.basex.query.QueryException: [FORG0001] Cannot cast to 
xs:double: [Ljava.lang.Object;@2f0539f0.
    at org.basex.query.QueryError.get(QueryError.java:1365) 
~[BaseX.jar:8.6.7]
    at org.basex.query.QueryError.castError(QueryError.java:1571) 
~[BaseX.jar:8.6.7]
    at org.basex.query.value.item.Dbl.parse(Dbl.java:180) 
~[BaseX.jar:8.6.7]
    at org.basex.query.value.item.Item.dbl(Item.java:134) 
~[BaseX.jar:8.6.7]
    at org.basex.query.value.type.AtomType.checkLong(AtomType.java:927) 
~[BaseX.jar:8.6.7]
    at org.basex.query.value.type.AtomType$20.cast(AtomType.java:331) 
~[BaseX.jar:8.6.7]
    at org.basex.query.value.type.AtomType$20.cast(AtomType.java:1) 
~[BaseX.jar:8.6.7]
    at org.basex.query.QueryContext.cast(QueryContext.java:733) 
~[BaseX.jar:8.6.7]
    at org.basex.query.QueryContext.bind(QueryContext.java:486) 
~[BaseX.jar:8.6.7]
    at org.basex.query.QueryProcessor.bind(QueryProcessor.java:129) 
~[BaseX.jar:8.6.7]
    at com.nw.basex.xquery.XQueryExecutor.bind(XQueryExecutor.java:89) 
~[com.nw.dasbox-2018-03-15.jar:?]
    at 
com.nw.basex.xquery.XQueryExecutor.execute(XQueryExecutor.java:107) 
~[com.nw.dasbox-2018-03-15.jar:?]
    at 
com.nw.dasbox.vdr.resolution.InlineXQueryResolutionEngine.evaluate(InlineXQueryResolutionEngine.java:91) 
~[com.nw.dasbox-2018-03-15.jar:?]

    ... 10 more