Search code examples
arangodbaqlfoxxarangojs

AQL: Bind parameter on operator


Is there a way to have bind parameter on operator ("<", "<=" etc ...) ? I'm working on a Foxx service.

Example :

const operator = '<'
const res = query`
  FOR v IN myCollection
  FILTER v.value ${operator} ${maxValue}
`

I can do it with db._query :

const operator = '<'
const res = db._query('
  FOR v IN myCollection
  FILTER v.value ${operator} @maxValue'
{ maxValue: 100 })


Solution

  • Normal bind parameters (with one @) can only be used for the values null, true, false, numbers, strings, arrays and objects. Collection bind parameters (with two @@) can be used where collection names are specified.

    Passing an operator via bind parameters is not possible in AQL, as it could likely change the meaning of a query, or render it totally invalid.

    Consider the following example:

    FOR v IN myCollection
    FILTER v.value @operator @maxValue
    

    This query does not even parse, regardless of what values are passed in the bind parameters. And this is a good thing, because otherwise one may pass something like @operator: "abc", @maxValue: ">=", which would mean the query can be parsed fine without bind parameters, but would produce a parse error with bind parameters injected.

    So the easiest solution here is to inject the comparison operator into the query via template string substituion, though of course you need to make sure the requested comparison operator is in a whitelisted of allowed operators. But you would need to do this even with bind parameters, as otherwise people could just send @operator: "!=" or @operator: "NOT IN" or other operators which you either don't expect or that can make your query more expensive.