saintsystems / odata-client-php

OData Client Library for PHP
MIT License
141 stars 103 forks source link

Guid primitive literals non compliant with OASIS OData url conventions (v4.0) #155

Closed kinekt4 closed 3 months ago

kinekt4 commented 3 months ago

I'm using a REST api and have been successful filtering by string and decimals etc.

But when filtering a guid column I get a 400 Bad Response with the following error:

A binary operator with incompatible types was detected. Found operand types 'Edm.Guid' and 'Edm.String' for operator kind 'Equal'.

I'm currently filtering like this:

$item = $odataClient->from('Item')->where('id', '=', 'ec11-80f1-0022489308a6')->get();

I see that the issue is related to the single quotes being added to the value in Grammar::prepareValue().

To prevent single quotes being added, it seems I have to explicitly define the type as a prefix Grammar::isSpecialPrimitiveDataType()

return preg_match("/^(binary|datetime|guid|time|datetimeoffset)(\'[\w\:\-\.]+\')$/i", $value);

So I've modified the guid value to something like this:

$item = $odataClient->from('Item')->where('id', '=', "guid'ec11-80f1-0022489308a6'")->get();

Which resulted in a different error.

Can anyone suggest anything else I can try?

Thanks!

Edit

Edit 02

Rest API

Test done via Postman Filter Response
id eq 'ec11-80f1-0022489308a6' Error: A binary operator with incompatible types was detected.
Found operand types 'Edm.Guid' and 'Edm.String' for operator kind 'Equal'.
id eq guid'ec11-80f1-0022489308a6' Error: Unrecognized 'Edm.String' literal...
id eq ec11-80f1-0022489308a6 OK
kinekt4 commented 3 months ago
kinekt4 commented 3 months ago
kinekt4 commented 3 months ago

Whereas PR #105 allows users to pass through the whole raw expression; eg.

$whereRaw = "id eq ec11-80f1-0022489308a6";
$item = $odataClient->from('Item')->whereRaw($whereRaw)->get();

My PR #156 only aims to pass through the raw value, while maintaining the regular syntax as before

$item = $odataClient->from('Item')->where('id', '=', "raw'ec11-80f1-0022489308a6'")->get();
kinekt4 commented 3 months ago

I found my solution in #137, I should do this instead (undocumented):

$item = $odataClient->from('Item')->whereKey('ec11-80f1-0022489308a6')->get();
anderly commented 1 month ago

Will see about updating samples and docs with this.

anderly commented 1 month ago

@kinekt4, also curious if the following would work for your case if it's an ID/PK field:

    $odataClient->from('Item')->find('ec11-80f1-0022489308a6');

This is example is on the wiki, but wanted to check if it worked in your example.