Determining if a node is a database node

Monday, 3 July 2023 · 4 messages · last reply 6 Jul 2023
EK
Eliot Kimber3 Jul 2023 21:55 #

I need to be able to determine if an arbitrary node is or is not a database node.

I implemented this function:

declare function util:isDatabaseNode($node as node()) as xs:boolean {
  let $isDbNode as xs:boolean :=
    try {
      let $nodeId as xs:integer? := db:node-id($node)
      (: let $msg := prof:dump(``[[DEBUG]   relpath:isDatabaseNode(): nodeId: "`{$nodeId}`"]``) :)
      return exists($nodeId)
    } catch * {
      (: let $msg := prof:dump(``[[DEBUG]   relpath:isDatabaseNode(): Got exception `{$err:code}` - `{$err:description}`]``) :)
      (: return :) false()
    }
  let $msg := prof:dump(``[[DEBUG]   relpath:isDatabaseNode(): Returning `{$isDbNode}``]``)
  return $isDbNode
};

With the prof:dump() calls commented out as shown here, it always returns true, even when it returned false.

If I comment in the prof:dumps then I get the expected correct false result.

This must be the result some optimization at compile time but I haven’t been able to find a construction of this function that works without the debug messages.

Is there a better way to determine if a node is a database node?

This is with 10.6.

Cheers,

E. _____________________________________________ Eliot Kimber Sr Staff Content Engineer O: 512 554 9368 M: 512 554 9368 servicenow.com<https://www.servicenow.com> LinkedIn<https://www.linkedin.com/company/servicenow> | Twitter<https://twitter.com/servicenow> | YouTube<https://www.youtube.com/user/servicenowinc> | Facebook<https://www.facebook.com/servicenow>

CG
Christian Grün4 Jul 2023 13:13 #

Hi Eliot,

The XQuery Specification allows implementations to simplify an expression if it always yields the same result in the case of success. As db:node-id never returns an empty sequence, BaseX rewrites exists(db:node-id()) to true().

You can use the following alternative:

declare function util:isDatabaseNode($node) {
  try {
    boolean(db:name($node))
  } catch db:node {
    false()
  }
};

It would be cleaner if we added a dedicated function for that in a future version of BaseX.

Cheers, Christian

Quoted text · Eliot Kimber · 75 lines
On Mon, Jul 3, 2023 at 9:55 PM Eliot Kimber <eliot.kimber at servicenow.com> wrote: > > I need to be able to determine if an arbitrary node is or is not a database node. > > > > I implemented this function: > > declare function util:isDatabaseNode($node as node()) as xs:boolean { > > let $isDbNode as xs:boolean := > > try { > > let $nodeId as xs:integer? := db:node-id($node) > > (: let $msg := prof:dump(``[[DEBUG] relpath:isDatabaseNode(): nodeId: "`{$nodeId}`"]``) :) > > return exists($nodeId) > > } catch * { > > (: let $msg := prof:dump(``[[DEBUG] relpath:isDatabaseNode(): Got exception `{$err:code}` - `{$err:description}`]``) :) > > (: return :) false() > > } > > let $msg := prof:dump(``[[DEBUG] relpath:isDatabaseNode(): Returning `{$isDbNode}``]``) > > return $isDbNode > > }; > > > > With the prof:dump() calls commented out as shown here, it always returns true, even when it returned false. > > > > If I comment in the prof:dumps then I get the expected correct false result. > > > > This must be the result some optimization at compile time but I haven’t been able to find a construction of this function that works without the debug messages. > > > > Is there a better way to determine if a node is a database node? > > > > This is with 10.6. > > > > Cheers, > > > > E. > > _____________________________________________ > > Eliot Kimber > > Sr Staff Content Engineer > > O: 512 554 9368 > > M: 512 554 9368 > > servicenow.com > > LinkedIn | Twitter | YouTube | Facebook
EK
Eliot Kimber5 Jul 2023 19:23 #

Thanks for the tip.

A db:is-node() function would be most handy.

In my case, I’m using transform with to augment content pulled from the database before doing processing that will vary depending on whether I have a database node (i.e., getting its node ID or database path) or I don’t.

Of course it would also be useful for functions that may operate on database nodes or content parsed from the file system.

Cheers,

Eliot

_____________________________________________ Eliot Kimber Sr Staff Content Engineer O: 512 554 9368 M: 512 554 9368 servicenow.com<https://www.servicenow.com> LinkedIn<https://www.linkedin.com/company/servicenow> | Twitter<https://twitter.com/servicenow> | YouTube<https://www.youtube.com/user/servicenowinc> | Facebook<https://www.facebook.com/servicenow>

Quoted text · Christian Grün · 98 lines
From: Christian Grün <christian.gruen at gmail.com> Date: Tuesday, July 4, 2023 at 4:14 AM To: Eliot Kimber <eliot.kimber at servicenow.com> Cc: basex-talk at mailman.uni-konstanz.de <basex-talk at mailman.uni-konstanz.de> Subject: Re: [basex-talk] Determining if a node is a database node [External Email] Hi Eliot, The XQuery Specification allows implementations to simplify an expression if it always yields the same result in the case of success. As db:node-id never returns an empty sequence, BaseX rewrites exists(db:node-id()) to true(). You can use the following alternative: declare function util:isDatabaseNode($node) { try { boolean(db:name($node)) } catch db:node { false() } }; It would be cleaner if we added a dedicated function for that in a future version of BaseX. Cheers, Christian On Mon, Jul 3, 2023 at 9:55 PM Eliot Kimber <eliot.kimber at servicenow.com> wrote: > > I need to be able to determine if an arbitrary node is or is not a database node. > > > > I implemented this function: > > declare function util:isDatabaseNode($node as node()) as xs:boolean { > > let $isDbNode as xs:boolean := > > try { > > let $nodeId as xs:integer? := db:node-id($node) > > (: let $msg := prof:dump(``[[DEBUG] relpath:isDatabaseNode(): nodeId: "`{$nodeId}`"]``) :) > > return exists($nodeId) > > } catch * { > > (: let $msg := prof:dump(``[[DEBUG] relpath:isDatabaseNode(): Got exception `{$err:code}` - `{$err:description}`]``) :) > > (: return :) false() > > } > > let $msg := prof:dump(``[[DEBUG] relpath:isDatabaseNode(): Returning `{$isDbNode}``]``) > > return $isDbNode > > }; > > > > With the prof:dump() calls commented out as shown here, it always returns true, even when it returned false. > > > > If I comment in the prof:dumps then I get the expected correct false result. > > > > This must be the result some optimization at compile time but I haven’t been able to find a construction of this function that works without the debug messages. > > > > Is there a better way to determine if a node is a database node? > > > > This is with 10.6. > > > > Cheers, > > > > E. > > _____________________________________________ > > Eliot Kimber > > Sr Staff Content Engineer > > O: 512 554 9368 > > M: 512 554 9368 > > servicenow.com > > LinkedIn | Twitter | YouTube | Facebook
CG
Christian Grün6 Jul 2023 13:25 #

Maybe we still need to find better terms than »database node« and »fragments« to describe the data structures that we use for XML structures (as described in [1]), as the current situation is even more complex:

1. we have fragments (e.g. as the result of <x/>) 2. we have volatile main-memory database nodes 3. we have persistent database nodes

…and db:node-id can only be used for persistent database nodes.

Quoted text · Eliot Kimber · 4 lines
> In my case, I’m using transform with to augment content pulled > from the database before doing processing that will vary > depending on whether I have a database node (i.e., getting > its node ID or database path) or I don’t.

Feel free to provide us with a little use case.

[1] https://docs.basex.org/wiki/Database_Module#Database_Nodes


⚡Generated with XQuery