Change HAS condition type to always use String in @whereConditions#2725
Conversation
- Rename DEFAULT_WHERE_HAS_CONDITIONS to DEFAULT_HAS_CONDITION for cleaner type names (WhereConditionsHasCondition vs WhereConditionsWhereHasConditions) - Rename createWhereHasConditionsInputType to createHasConditionInputType - Add tests for nested HAS conditions and AND/OR combinations - Clarify CHANGELOG entry as a fix Co-Authored-By: Claude <noreply@anthropic.com>
…here-has-condition # Conflicts: # CHANGELOG.md
- Delegate createHasConditionInputType to createWhereConditionsInputType to eliminate code duplication (37 lines reduced to 6) - Replace assert() with $this->assertInstanceOf() for PHPUnit consistency Co-Authored-By: Claude <noreply@anthropic.com>
The delegation to createWhereConditionsInputType caused incorrect type references. Keep methods separate for clarity and correctness. Co-Authored-By: Claude <noreply@anthropic.com>
|
Released with https://github.com/nuwave/lighthouse/releases/tag/v6.64.2, thank you |
|
This ended up being a breaking change for my project, despite being released as a patch. |
|
@oortasertecfarma How did this break your project? I was inclined to agree with @DrPowerSlam assessment:
|
Can't speak for @oortasertecfarma , but this was a breaking change for me as well. This increased the cached schema file size from 17mb to 21mb, which caused memory exhaustion errors in ASTCache.php fromCacheOrBuild method, line 64, while reading the cache file. |
|
After looking into it, the issue that occurred in my project after upgrading was caused by a custom override of manipulateArgDefinition in WhereConditionsBaseDirective, which already allowed the use of String in HAS conditions and covered a slightly broader use case. Regarding the schema size mentioned above, I also checked it on my side. |
|
+1 for projects where it was a breaking change |
|
@trckster Can you please elaborate? So far, nobody has articulated how and why this was a breaking change. |
|
@spawnia sure. I will reconstruct for you logic that was working previously. PHP: GraphQL: # Model - Book (books: id)
# Model -Tag (tags: id)
# Junction model - BookTag (books_tags: book_id, tag_id)
type Book {
id: ID!
}
enum QueryBookWhereEnum {
BOOKS_TAGS_TAG_ID @enum(value: "books_tags.tag_id")
}
extend type Query {
books(where: _ @whereConditions(columnsEnum: "QueryBookWhereEnum")): [Book!]!
}
# It is example with N-to-N relation, as it was on the project
# Likely is reproducible with 1-N relationBook Eloquent model: /**
* Used by book filter BOOKS_TAGS_TAG_ID
*/
public function bookTags(): IlluminateHasMany
{
return $this->hasMany(BookTag::class);
}GraphQL query for filtering books by certain tag id: "where": {
"HAS": {
"relation": "bookTags",
"condition": {
"AND": [
{
"column": "BOOKS_TAGS_TAG_ID",
"value": "<id of the tag>"
}
]
}
}
},
So column value |
|
@trckster That is exactly the problem described in the original issue. Your enum is added to the Which means that you can use So you could end up with a query that is similar to In your case, you've just added an enum value that makes the logic work for this 1 example, and you would just have to pass the string |
|
@DrPowerSlam so it's like we were exploiting library's flaw and now it is fixed, got you. Thank you for clarification. I guess this change is not backward compatible, so major version should be bumped. What do you think? Also, now if I pass |
|
@trckster It's not backwards compatible, but at the same time it's so hard to use correctly that the fix will impact a minimum of people. I'm of course sorry it has affected you, but I think you would have hit a roadblock if you continued (mis)using this functionality. I can't decide on which which version this fix should be bundled with (and after 2 weeks we've only had 1 legitimate use-case where it broke something), I'm just a contributor, not a maintainer. On your last point, I think you would have to create a custom directive that checks if an API consumer is inputting something that isn't allowed. The schema can't really validate an input string, so you would have to do it in runtime. |
|
@DrPowerSlam makes sense, thanks for answers! |
#2723
Changes
Changes the condition type of
HASarguments in@whereConditionsto always useStringtype, so thecolumntype isn't inherited from the parent node.Breaking changes
Technically this is a breaking change, since users that currently use the unupdated code will go from an Enum type to a String type.
However, I would argue that it's almost impossible to correctly use the current functionality, since you need a perfect overlap between columns in a node and all its relations to make it work.