Does the parser support `contains(field, value)` comparisons?
al-the-x opened this issue · comments
Hello! Thank you for this wonderful contribution to the community! We have been using odata-query
with our Django / DRF project to provide OData representations of our 1st-party objects in Salesforce via External Objects, but as we are expanding the usage of OData, we have encountered some difficulty with the parser. For example, when exposing one of our Django models via a filterable OData API for Salesforce, we encountered this error:
TypeException
Cannot apply 'Eq' to 'Call(func=Identifier(name='contains'), args=[Identifier(name='category'), String(val='danielle hutchens')])'
From odata_query/django/django_q.py
in visit_Compare
at line 194
:
node
: Compare(comparator=Eq(), left=Call(func=Identifier(name='contains'), args=[Identifier(name='category'), String(val='danielle hutchens')]), right=Boolean(val='true'))
. . .
From odata_query/django/shorthand.py
in apply_odata_query
at line 24
:
odata_query
:
"contains(category,'danielle hutchens') eq true or contains(email,'danielle hutchens') eq true or contains(filename,'danielle hutchens') eq true or contains(file_id,'danielle hutchens') eq true or contains(path,'danielle hutchens') eq true or contains(revision,'danielle hutchens') eq true or contains(content_hash,'danielle hutchens') eq true or contains(subcategory,'danielle hutchens') eq true or contains(hyker__sfaccountid,'danielle hutchens') eq true or contains(hyker__sfopportunityid,'danielle hutchen...
Can you confirm whether odata-query
supports these kinds of comparisons? Are we (or Salesforce External Objects) doing something wrong?
Hey, glad you like the library, thanks!
It seems that this is a bug, specifically when using the Django backend. I've tested against both our SQLAlchemy app and Django app, and the Django test does indeed fail. Good catch!
In the case of contains
however, the comparison isn't strictly necessary as contains
already returns a boolean. So your example should work if you just use contains(category,'danielle hutchens') or contains(email,'danielle hutchens') or ...
(without the eq true
).
I'm gonna look into this, as your query is also correct and should just work.
Hmmm, I though I'd found a solution in db85807. Turns out it relies on new functionality only introduced in Django 4. I'll have to rethink my fix!
Happy to contribute here. For our use case, Salesforce is the client, so we don't really have control of the query that is constructed. I suppose we could inspect the AST and drop the Eq
with a left-hand Call
for the Call
itself, if that's the issue?
Hey @al-the-x ,
sorry to keep you waiting for so long. I felt like I was perpetually within 5 minutes of fixing this, but things kept popping up.
#20 would fix this issue, but includes quite a big change to how Django queries are constructed (in line with new Django 4 features). I wouldn't recommend updating production software blindly, as some issues are present relating to upstream Django issues (e.g. https://code.djangoproject.com/ticket/33705).
Your fix would definitely be a good band-aid if updating is not an option!