Add a possibility to identify a variable that has not been assigned yet. ("undefined")

Moved from GitHub dgraph/4619

Posted by koculu:

What you wanted to do

I want to increment a scalar predicate with upsert operation.
If the counter predicate is missing in a record, upsert operation should be able to set initial value.
I cannot set initial value if predicate value is missing because there is no way to check if some variable is undefined.

What you actually did

upsert {
      query{
      	q(func: uid(0x4e22)){         	
          v as visit-count
          incrementedValue as math(cond(v > 0, v+1, 1))
        }
      }         
      mutation {
        set {            
          	<0x4e22> <visit-count> val(incrementedValue) .
        }
      }
}

Why that wasn’t great, with examples

I am getting following exception.
Error: t: : Expected a value variable in cond but missing.
There is no way to check if some variable is missing.

There should be a function isMissing(variable) to check if a variable is missing.

Any external references to support your case

MichelDiz commented :

Sure this would be a good feature to work with true/false statements. Undefined should be identified as false by the parser. I believe that this would be useful in several other situations.

But for now, here’s a workaround for you.

Cheers.

upsert {
      query{
      	targt as q(func: uid(0x2)) {
          v as <visit-count>
          check as count(visit-count)
          incrementedValue as math(cond(check > 0, v+1, 1))
            }
          }
      mutation {
        set {
          	uid(targt) <visit-count> val(incrementedValue) .
        }
      }
}

shravan-v commented :

What is the status of this feature? Has it been released?

MichelDiz commented :

No, it needs some engineer to take a look and accept it or not to the backlog.

MichelDiz commented :

Internally, this issue was considered reasonable. For this fact, I will add it to the back-log.

Anyone interested in this behavior in the variables, please give your thumbs up. In the main comment of that issue. So we understand the level of popularity and maybe prioritize it based on that.

sleto-it commented :

Hi @shravan-v, please could you tell us if the workaround @MichelDiz shared worked for you?

Many Thanks,

shravan-v commented :

@sleto-it What workaround are you talking about? Can you elaborate?

paulrostorp commented :

I have a different use case:
When I do a query like this:

query {
  typeA(func: type(typeA)) @filter(eq(pred1, false)) { myVal as pred2 }
  typeB(func: type(typeB)) @filter(eq(pred3, val(myVal)) { uid }
}

and when the first query (for typeA) doesn’t match any data, myVal is naturally null/undefined, and the transaction fails with

UNKNOWN: : eq expects atleast 1 argument

I wouldn’t expect this to fail, I would expect the query to return a payload like this:

data: {
  typeA: [],
  typeB: []
}

I tried containing the problem by adding another condition to the filter and grouping them with AND like this:

typeB(func: type(typeB)) @filter(gt(len(myVal), 0) AND eq(pred3, val(myVal)) { uid }

… but the second function is still processed and the error persists.