Filtering a custom asset listing through the High-Level API on its custom fields returns a 500 as soon as the filter is anything more than a single unparenthesised comparison.
Endpoint: GET /Assets/Custom/{schema}
Using the Test01 fixture custom fields, these all return 500:
- custom_fields.teststring=="Test String A";custom_fields.testboolean=="0" (two custom fields, AND)
- custom_fields.teststring=="Test String A",custom_fields.teststring=="Test String B" (two custom fields, OR)
- (custom_fields.teststring=="Test String A") (one custom field, in a group)
A single custom-field comparison without parentheses works, which is why the existing search test only covers that one shape.
The cause is in Glpi\Api\HL\RSQL\Parser::parse(). Custom fields are computed properties, so their SQL goes into the HAVING string, but the logical separators (AND/OR) and the group parentheses are only ever appended to the WHERE string. So two custom-field predicates end up concatenated in HAVING with no operator between them, and a group leaves an empty () sitting in WHERE. Both produce invalid SQL.
The awkward part is that an OR between a regular field and a computed field can't really be expressed by splitting into WHERE and HAVING, and the search groups by _.id, so simply moving everything into HAVING has ONLY_FULL_GROUP_BY implications for joined columns.
Is the WHERE/HAVING split meant to only support ANDed regular plus computed filters, or should these cases work? If you want it fixed I will open a PR, I just wanted your steer on the intended behaviour for OR across the boundary before writing it.
Filtering a custom asset listing through the High-Level API on its custom fields returns a 500 as soon as the filter is anything more than a single unparenthesised comparison.
Endpoint: GET /Assets/Custom/{schema}
Using the Test01 fixture custom fields, these all return 500:
A single custom-field comparison without parentheses works, which is why the existing search test only covers that one shape.
The cause is in Glpi\Api\HL\RSQL\Parser::parse(). Custom fields are computed properties, so their SQL goes into the HAVING string, but the logical separators (AND/OR) and the group parentheses are only ever appended to the WHERE string. So two custom-field predicates end up concatenated in HAVING with no operator between them, and a group leaves an empty () sitting in WHERE. Both produce invalid SQL.
The awkward part is that an OR between a regular field and a computed field can't really be expressed by splitting into WHERE and HAVING, and the search groups by _.id, so simply moving everything into HAVING has ONLY_FULL_GROUP_BY implications for joined columns.
Is the WHERE/HAVING split meant to only support ANDed regular plus computed filters, or should these cases work? If you want it fixed I will open a PR, I just wanted your steer on the intended behaviour for OR across the boundary before writing it.