-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Filters for sub models don't generate the right subqueries #25
Comments
@RichardLindhout any luck to fix this? here is an example of the issue in my case
|
I think issue is described here. cannot think about options to fix then |
Hey I'll try to invest some time in this soon, maybe today! |
What is the code what cause this it looks like this is another issue |
I ment what is the graphql filter you sent? |
{
appointments(filter: {
where : {
startsAt: "2020-07-08T23:00:00Z",
endsAt: "2020-07-08T23:20:00Z",
appointmentParticipants : {
account : {
id : {
equalTo: "df95dc13-8673-40c0-ada4-203cf72e20ff"
}
}
}
}
}) {
id
startsAt
endsAt
status
}
} subQueryMods := AppointmentParticipantWhereToMods(m, !hasForeignKeyInRoot)
if len(subQueryMods) > 0 {
subQuery := models.AppointmentParticipants(append(subQueryMods, qm.Select("1"))...)
queryMods = appendSubQuery(queryMods, subQuery.Query) // <-- issue happens here
} |
I can't reproduce the error you are having, but I think I know a way to fix this issue but I would like to make this library more polished and testable first. I don't have time in the next few weeks to work around this. Will surely fix in the future + new features but I have a few private projects I need to finish and work on before I can work on open source again. |
If you could drop me a few lines about fix idea you have I could try to make it work |
that quite dirty hack, but works var (
replaceQuestion = regexp.MustCompile(`(\$\d{1,2})`)
)
func appendSubQuery(queryMods []qm.QueryMod, q *queries.Query) []qm.QueryMod {
qs, args := queries.BuildQuery(q)
qsClean := strings.TrimSuffix(qs, ";")
res := replaceQuestion.ReplaceAllStringFunc(qsClean, func(m string) string {
parts := replaceQuestion.FindStringSubmatch(m)
if len(parts) > 1 {
return "?"
}
return ""
})
return append(queryMods, qm.Where(fmt.Sprintf("EXISTS(%v)", res), args...))
} |
i just think it probably worth to ask |
like this 🤣 func appendSubQuery(queryMods []qm.QueryMod, q *queries.Query) []qm.QueryMod {
// all nasty job below is to tell query builder not to replace ? placeholders
member := reflect.ValueOf(q).Elem().FieldByName("dialect")
dialectPtr := (**drivers.Dialect)(unsafe.Pointer(member.UnsafeAddr()))
dialect := **dialectPtr
dialect.UseIndexPlaceholders = false
*dialectPtr = &dialect
qs, args := queries.BuildQuery(q)
qsClean := strings.TrimSuffix(qs, ";")
return append(queryMods, qm.Where(fmt.Sprintf("EXISTS(%v)", qsClean), args...))
} |
I think this issue is another problem too, even if the arguments worked there would still be issues where there are too much results. This looks more like a sqlboiler issue/enhancement. Anyway I'm fixing the issue title and will try to look if I have the same issue with more filters |
Fixed the issue described (not @troian 's case yet). However it only works 2/3 level nested at the moment since we need to pass all other queryMods to the sub queries too so deeper filters still need a better bugfix for this so we can go endless deeply with filters SELECT
*
FROM
`block`
WHERE
`block`.`organization_id` = 1
AND
(
EXISTS
(
SELECT
1
FROM
`flow_block`
WHERE
(
EXISTS
(
SELECT
1
FROM
`block`
WHERE
(
EXISTS
(
SELECT
1
FROM
`block_choice`
WHERE
(
EXISTS
(
SELECT
1
FROM
`block`
WHERE
(
EXISTS
(
SELECT
1
FROM
`block_choice`
WHERE
(
id = 11
)
AND
(
block_choice.block_id = block.id
)
)
)
)
)
AND
(
block_choice.block_id = block.id
)
)
)
)
)
AND
(
flow_block.block_id = block.id
)
)
)
; Need to become SELECT
*
FROM
`block`
WHERE
`block`.`organization_id` = 1
AND
(
EXISTS
(
SELECT
1
FROM
`flow_block`
WHERE
(
EXISTS
(
SELECT
1
FROM
`block`
WHERE
(
EXISTS
(
SELECT
1
FROM
`block_choice`
WHERE
(
EXISTS
(
SELECT
1
FROM
`block`
WHERE
(
EXISTS
(
SELECT
1
FROM
`block_choice`
WHERE
(
id = 11
)
AND
(
block_choice.block_id = block.id
)
AND
(
flow_block.block_id = block.id
)
)
)
)
)
AND
(
block_choice.block_id = block.id
)
AND
(
flow_block.block_id = block.id
)
)
)
)
)
AND
(
flow_block.block_id = block.id
)
)
)
; |
@troian Maybe something is wrong with the time filter. I have the following query which I think is the same as yours relationship wise
SELECT * FROM `block` WHERE `block`.`organization_id` = 1 AND (block_type = 'CHOICE' AND EXISTS(SELECT 1 FROM `flow_block` WHERE (block_id = 4) AND (flow_block.block_id = block.id))); |
Or maybe it's postgres related.. Hmm. Maybe we should ask Aaron. |
@troian try v2.1.4 and re-generate the filters |
The issue is definitely in there SELECT * FROM "appointment" WHERE (((starts_at >= $1 AND starts_at < $2) OR (ends_at >= $3 AND ends_at < $4)) AND EXISTS(SELECT 1 FROM "appointment_participant" WHERE (account_id = $1))); |
How do get this sql, I only got
|
I think this is something sqlboiler should handle to be honest. It should see that subqueries are provided and ++ the indexes |
Ok forgot about this xD
|
Yah, issue happens when member := reflect.ValueOf(q).Elem().FieldByName("dialect")
dialectPtr := (**drivers.Dialect)(unsafe.Pointer(member.UnsafeAddr()))
dialect := **dialectPtr
dialect.UseIndexPlaceholders = false
*dialectPtr = &dialect |
Ok, let's discuss this issue with Aaron :) |
Aaron said in Slack he has no time a.t.m. so I think we could maybe workaround this ourselves or use the reflect hack for the time being. Or do a pull request for sqlboiler. I think my usage of the BuildQuery is not done before but the alternative is all raw queries which I want to prevent. |
Probably it worth to do it with reflect hack (or whatever option would fit). as this issue is quite a big hold |
I've proposed something to Aaron: volatiletech/sqlboiler#482 (comment) We could probably export a more advanced query builder with some options |
Then we can disable the questionMarks without using reflect. But it would need a PR to sqlboiler |
This comment has been minimized.
This comment has been minimized.
I'm interested though how this understands the arguments in the parent query understand that the arguments of the subquery. Can we have both query arguments in the parent query and the subquery etc . Before and after a sub query, we need some tests for this on sqlboiler too. |
@RichardLindhout i'll give it a check but atm it looks about right. |
Hey @troian thanks for your workaround! I have released this under https://github.com/web-ridge/gqlgen-sqlboiler/releases/tag/v2.1.5 To enable it:
|
When I filter on
It results in the following query:
This results in all almost all flowblocks returning while it should only return flowblocks which contain a block with this title so the query should be:
The text was updated successfully, but these errors were encountered: