guregu / dynamo

expressive DynamoDB library for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Filter should add parentheses around AND'ed expressions by default

pquerna opened this issue · comments

Hello!

We have some generic functions that are building Queries--- we ran into a case where it seemed we were getting back documents we expected to be filtered.

Short pseudo-code example:

q = q.Filter("('expires_at' >= ?) OR ('expires_at' = ?)", time.Now().Unix(), 0)
q = q.Filter("deleted = ?", true)

When this was generated into a FilterExpression to dynamo, it would logically do this:

 true || false && false

fix on our side, was adding parentheses around our OR'ed expression:

q = q.Filter("(('expires_at' >= ?) OR ('expires_at' = ?))", time.Now().Unix(), 0)
q = q.Filter("deleted = ?", true)

which would result in:

(true || false) && false

Which would then correctly filter out documents. I think I've seen other "ORM" / SQL builder libraries wrap all AND'ed expressions with () to prevent this kind of issue.

Thoughts?

Hello, it tries to add parenthesis but it's not very smart about it. You're tripping an edge case where it thinks that you've already wrapped the expression.

In your example, you could fix it by changing it to:

q = q.Filter("'expires_at' >= ? OR 'expires_at' = ?", time.Now().Unix(), 0)
q = q.Filter("deleted = ?", true)

which should do what you want (expires >= ? OR expires = ?) AND (deleted = ?).

I'd like to just shove parenthesis in every AND but DynamoDB complains about unnecessary parentheses (why??) and errors out. But if your second example works, maybe they changed this? I'll do some investigating. This could also be fixed by properly analyzing the parenthesis instead of just looking at the start and end. Either way I'll fix it, thanks.

(Maybe DynamoDB only dislikes expressions like ((A)) and ((A) (B)) is ok? 🤔 )

OK, this should be fixed in v1.10.3 which I have just released.

Thank you for the quick comment and fix!