[#7444] remove unnecessery subquery when resolving single back-relation fields
This commit is contained in:
@@ -547,15 +547,11 @@ func (r *runner) processActiveProps() (*search.ResolverResult, error) {
|
|||||||
// ---
|
// ---
|
||||||
cleanProp := inflector.Columnify(prop)
|
cleanProp := inflector.Columnify(prop)
|
||||||
cleanBackFieldName := inflector.Columnify(backRelField.Name)
|
cleanBackFieldName := inflector.Columnify(backRelField.Name)
|
||||||
|
|
||||||
newTableAlias := r.activeTableAlias + "_" + cleanProp + r.resolver.joinAliasSuffix
|
newTableAlias := r.activeTableAlias + "_" + cleanProp + r.resolver.joinAliasSuffix
|
||||||
newCollectionName := inflector.Columnify(backCollection.Name)
|
newCollectionName := inflector.Columnify(backCollection.Name)
|
||||||
|
|
||||||
isBackRelMultiple := backRelField.IsMultiple()
|
isBackRelMultiple := backRelField.IsMultiple()
|
||||||
if !isBackRelMultiple {
|
|
||||||
// additionally check if the rel field has a single column unique index
|
|
||||||
_, hasUniqueIndex := dbutils.FindSingleColumnUniqueIndex(backCollection.Indexes, backRelField.Name)
|
|
||||||
isBackRelMultiple = !hasUniqueIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
if !isBackRelMultiple {
|
if !isBackRelMultiple {
|
||||||
err := r.resolver.registerJoin(
|
err := r.resolver.registerJoin(
|
||||||
@@ -592,6 +588,11 @@ func (r *runner) processActiveProps() (*search.ResolverResult, error) {
|
|||||||
// ---
|
// ---
|
||||||
if isBackRelMultiple {
|
if isBackRelMultiple {
|
||||||
r.withMultiMatch = true // enable multimatch if not already
|
r.withMultiMatch = true // enable multimatch if not already
|
||||||
|
} else if !r.withMultiMatch {
|
||||||
|
// additionally check if the rel field has a single column unique index;
|
||||||
|
// if not - apply a multi-match check
|
||||||
|
_, hasUniqueIndex := dbutils.FindSingleColumnUniqueIndex(backCollection.Indexes, backRelField.Name)
|
||||||
|
r.withMultiMatch = !hasUniqueIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
newTableAlias2 := r.multiMatchActiveTableAlias + "_" + cleanProp + r.resolver.joinAliasSuffix
|
newTableAlias2 := r.multiMatchActiveTableAlias + "_" + cleanProp + r.resolver.joinAliasSuffix
|
||||||
|
|||||||
@@ -127,14 +127,14 @@ func TestRecordFieldResolverUpdateQuery(t *testing.T) {
|
|||||||
expectQuery string
|
expectQuery string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"non relation field (with all default operators)",
|
"none relation field (with all default operators)",
|
||||||
"demo4",
|
"demo4",
|
||||||
"title = true || title != 'test' || title ~ 'test1' || title !~ '%test2' || title > 1 || title >= 2 || title < 3 || title <= 4",
|
"title = true || title != 'test' || title ~ 'test1' || title !~ '%test2' || title > 1 || title >= 2 || title < 3 || title <= 4",
|
||||||
false,
|
false,
|
||||||
"SELECT `demo4`.* FROM `demo4` WHERE ([[demo4.title]] = 1 OR [[demo4.title]] IS NOT {:TEST} OR [[demo4.title]] LIKE {:TEST} ESCAPE '\\' OR [[demo4.title]] NOT LIKE {:TEST} ESCAPE '\\' OR [[demo4.title]] > {:TEST} OR [[demo4.title]] >= {:TEST} OR [[demo4.title]] < {:TEST} OR [[demo4.title]] <= {:TEST})",
|
"SELECT `demo4`.* FROM `demo4` WHERE ([[demo4.title]] = 1 OR [[demo4.title]] IS NOT {:TEST} OR [[demo4.title]] LIKE {:TEST} ESCAPE '\\' OR [[demo4.title]] NOT LIKE {:TEST} ESCAPE '\\' OR [[demo4.title]] > {:TEST} OR [[demo4.title]] >= {:TEST} OR [[demo4.title]] < {:TEST} OR [[demo4.title]] <= {:TEST})",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"non relation field (with all opt/any operators)",
|
"none relation field (with all opt/any operators)",
|
||||||
"demo4",
|
"demo4",
|
||||||
"title ?= true || title ?!= 'test' || title ?~ 'test1' || title ?!~ '%test2' || title ?> 1 || title ?>= 2 || title ?< 3 || title ?<= 4",
|
"title ?= true || title ?!= 'test' || title ?~ 'test1' || title ?!~ '%test2' || title ?> 1 || title ?>= 2 || title ?< 3 || title ?<= 4",
|
||||||
false,
|
false,
|
||||||
@@ -292,7 +292,7 @@ func TestRecordFieldResolverUpdateQuery(t *testing.T) {
|
|||||||
"demo3",
|
"demo3",
|
||||||
"demo4_via_rel_one_cascade.id = true",
|
"demo4_via_rel_one_cascade.id = true",
|
||||||
false,
|
false,
|
||||||
"SELECT DISTINCT `demo3`.* FROM `demo3` LEFT JOIN `demo4` `demo3_demo4_via_rel_one_cascade` ON [[demo3.id]] IN (SELECT [[__je_demo3_demo4_via_rel_one_cascade.value]] FROM json_each(CASE WHEN iif(json_valid([[demo3_demo4_via_rel_one_cascade.rel_one_cascade]]), json_type([[demo3_demo4_via_rel_one_cascade.rel_one_cascade]])='array', FALSE) THEN [[demo3_demo4_via_rel_one_cascade.rel_one_cascade]] ELSE json_array([[demo3_demo4_via_rel_one_cascade.rel_one_cascade]]) END) {{__je_demo3_demo4_via_rel_one_cascade}}) WHERE ((([[demo3_demo4_via_rel_one_cascade.id]] = 1) AND (NOT EXISTS (SELECT 1 FROM (SELECT [[__mm_demo3_demo4_via_rel_one_cascade.id]] as [[multiMatchValue]] FROM `demo3` `__mm_demo3` LEFT JOIN `demo4` `__mm_demo3_demo4_via_rel_one_cascade` ON [[__mm_demo3.id]] IN (SELECT [[__je___mm_demo3_demo4_via_rel_one_cascade.value]] FROM json_each(CASE WHEN iif(json_valid([[__mm_demo3_demo4_via_rel_one_cascade.rel_one_cascade]]), json_type([[__mm_demo3_demo4_via_rel_one_cascade.rel_one_cascade]])='array', FALSE) THEN [[__mm_demo3_demo4_via_rel_one_cascade.rel_one_cascade]] ELSE json_array([[__mm_demo3_demo4_via_rel_one_cascade.rel_one_cascade]]) END) {{__je___mm_demo3_demo4_via_rel_one_cascade}}) WHERE `__mm_demo3`.`id` = `demo3`.`id`) {{__smTEST}} WHERE NOT ([[__smTEST.multiMatchValue]] = 1)))))",
|
"SELECT DISTINCT `demo3`.* FROM `demo3` LEFT JOIN `demo4` `demo3_demo4_via_rel_one_cascade` ON [[demo3_demo4_via_rel_one_cascade.rel_one_cascade]] = [[demo3.id]] WHERE ((([[demo3_demo4_via_rel_one_cascade.id]] = 1) AND (NOT EXISTS (SELECT 1 FROM (SELECT [[__mm_demo3_demo4_via_rel_one_cascade.id]] as [[multiMatchValue]] FROM `demo3` `__mm_demo3` LEFT JOIN `demo4` `__mm_demo3_demo4_via_rel_one_cascade` ON [[__mm_demo3_demo4_via_rel_one_cascade.rel_one_cascade]] = [[__mm_demo3.id]] WHERE `__mm_demo3`.`id` = `demo3`.`id`) {{__smTEST}} WHERE NOT ([[__smTEST.multiMatchValue]] = 1)))))",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"back relations via single relation field (with unique index)",
|
"back relations via single relation field (with unique index)",
|
||||||
@@ -334,7 +334,7 @@ func TestRecordFieldResolverUpdateQuery(t *testing.T) {
|
|||||||
"demo1",
|
"demo1",
|
||||||
"view1_via_rel_one.rel_many.created ?> true",
|
"view1_via_rel_one.rel_many.created ?> true",
|
||||||
true,
|
true,
|
||||||
"SELECT DISTINCT `demo1`.* FROM `demo1` LEFT JOIN `view1` `demo1_view1_via_rel_one` ON [[demo1.id]] IN (SELECT [[__je_demo1_view1_via_rel_one.value]] FROM json_each(CASE WHEN iif(json_valid([[demo1_view1_via_rel_one.rel_one]]), json_type([[demo1_view1_via_rel_one.rel_one]])='array', FALSE) THEN [[demo1_view1_via_rel_one.rel_one]] ELSE json_array([[demo1_view1_via_rel_one.rel_one]]) END) {{__je_demo1_view1_via_rel_one}}) LEFT JOIN json_each(CASE WHEN iif(json_valid([[demo1_view1_via_rel_one.rel_many]]), json_type([[demo1_view1_via_rel_one.rel_many]])='array', FALSE) THEN [[demo1_view1_via_rel_one.rel_many]] ELSE json_array([[demo1_view1_via_rel_one.rel_many]]) END) `__je_demo1_view1_via_rel_one_rel_many` LEFT JOIN `users` `demo1_view1_via_rel_one_rel_many` ON [[demo1_view1_via_rel_one_rel_many.id]] = [[__je_demo1_view1_via_rel_one_rel_many.value]] WHERE [[demo1_view1_via_rel_one_rel_many.created]] > 1",
|
"SELECT DISTINCT `demo1`.* FROM `demo1` LEFT JOIN `view1` `demo1_view1_via_rel_one` ON [[demo1_view1_via_rel_one.rel_one]] = [[demo1.id]] LEFT JOIN json_each(CASE WHEN iif(json_valid([[demo1_view1_via_rel_one.rel_many]]), json_type([[demo1_view1_via_rel_one.rel_many]])='array', FALSE) THEN [[demo1_view1_via_rel_one.rel_many]] ELSE json_array([[demo1_view1_via_rel_one.rel_many]]) END) `__je_demo1_view1_via_rel_one_rel_many` LEFT JOIN `users` `demo1_view1_via_rel_one_rel_many` ON [[demo1_view1_via_rel_one_rel_many.id]] = [[__je_demo1_view1_via_rel_one_rel_many.value]] WHERE [[demo1_view1_via_rel_one_rel_many.created]] > 1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recursive back relations with non-empty list rule",
|
"recursive back relations with non-empty list rule",
|
||||||
|
|||||||
Reference in New Issue
Block a user