Unexpected behavior with func: uid(...) when UID is malformed, or node is nonexistent

There are two misleading things that happen when using the uid() func in certain scenarios:

  1. When the UID is malformed (i.e. doesn’t follow the ‘0x123abc’ format), it returns the error “Some variables are used but not defined”.
query getNode {
   someNode(func: uid(bad-uid) {
      uid
   }
}

->

Error: 2 UNKNOWN: Some variables are used but not defined
    Defined:[]
    Used:[bad-uid]
  1. When querying for a node with a UID that does not exist, the query returns a node with that UID
{
  someNode(func: uid(0x9999999)) {
    uid
    name
  }
}

->

"data": {
    "someNode": [
      {
        "uid": "0x9999999"
      }
    ]
  }

In both of these cases, I’d expect some kind of “Node does not exist” error.

For the first scenario, I can always validate the UID before making the query. Do UIDs always start with 0x?

For the second - what’s the best way to handle this?

if you use it this way it will return an error. For Dgraph does not recognize this “bad-uid” line as something intelligible to the required function (uid). So Dgraph will assume it’s a variable. and return the error:
Some variables are used but not defined Defined:[] Used:[bad-uid]Preformatted textid]

There is no way to cause UID query function error, return null or empty. You will always get some response. The only way to get an empty answer is by doing an indexed search or by kinds.

Yes

Create positive Kinds for this (or some indexing). For example, you need to know if your Dgraph has a specific Node type. Whether it exists or not. Through Kind you can get this answer.

here about kinds: https://docs.dgraph.io/howto/#giving-nodes-a-type

For example, you need to know if your Dgraph has a specific Node type. Whether it exists or not. Through Kind you can get this answer.

Let’s say you create a kind to identify whether or not there is user registration in your DB and other to boards.

{
 set {
    _:Alice <name> "Alice" .
    _:Alice <_User> " " .
    _:Alice <city> "San Francisco" .
    _:Alice <friend> _:Bob .

    _:Bob <name> "Bob" .
    _:Bob <_User> " " .
    _:Bob <city> "San Francisco" .
 }
}

Your query for users would be:

{
  q(func: has(_User)) {
    uid
    name
    city
    friend {
         name
         city
     }
  }
}

This query would return two users.

But Your query for boards (which do not yet exist) would be:

{
  q(func: has(_Board)) {
    uid
    titler
    body
    ~owner {
         name
         city
     }
  }
}

This query would return empty.

1 Like

Wonderful, thank you!

1 Like