BaseXdb/basex

XQuery: Drop Type Checks at Runtime

Closed this issue · 2 comments

The type of the function parameter…

declare function local:a($a as xs:integer?) { if(exists($a)) { local:a(()) } };
local:a(1)

…is dropped at the end of the compile step:

declare function local:a($a) { if(exists($a)) { local:a(()) } };
local:a(1)

In the following case, this doesn’t work yet, although local:b is never called:

declare function local:a($a as xs:integer?) {
  if(exists($a)) then local:a(()) else ()
};
declare function local:b($b as xs:integer) {
  local:a($b)
};
local:a(1)

Update: It does not work exactly because local:b is never called. As its function body is not optimized, the type of $b is not propagated to the variable reference in local:a($b).

Another example:

declare function local:a($ids as xs:integer*) {
  if (exists($ids)) then local:b(head($ids))
};
declare function local:b($id as xs:integer) {
  if($id > 1) then 1 else local:b($id)
};
local:a(10)

Update: The static type of head($ids) is xs:integer?. At runtime, it will always be xs:integer, but this cannot be detected at compile time. Workaround to get rid of the (cheap) type check: exactly-one(head($ids)).

Discarded (does not pay off).