From 12bff33f8b890fae4f9dc967270232c35537510a Mon Sep 17 00:00:00 2001 From: Julien Date: Fri, 17 Jan 2020 16:26:17 +0100 Subject: [PATCH 1/2] fix(connector-jdbc): remove unnecessary join on nested filter When using nested filter on an id, the relation table already owns the if columns, so there is no need for an additional join. Check that the only column we're filtering on is id, then rewrite the condition and remove the join. --- .../database/FilterConditionBuilder.scala | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/server/connectors/api-connector-jdbc/src/main/scala/com/prisma/api/connector/jdbc/database/FilterConditionBuilder.scala b/server/connectors/api-connector-jdbc/src/main/scala/com/prisma/api/connector/jdbc/database/FilterConditionBuilder.scala index d374b10845..f512886c6b 100644 --- a/server/connectors/api-connector-jdbc/src/main/scala/com/prisma/api/connector/jdbc/database/FilterConditionBuilder.scala +++ b/server/connectors/api-connector-jdbc/src/main/scala/com/prisma/api/connector/jdbc/database/FilterConditionBuilder.scala @@ -90,6 +90,16 @@ trait FilterConditionBuilder extends BuilderBase { val newAlias = relationField.relatedModel_!.dbName + "_" + alias val invertConditionOfSubSelect = relationFilter.condition == EveryRelatedNode + def getNestedNonRelationalQuery(nested: Filter) = { + val condition = buildConditionForFilter(nested, newAlias) + sql + .select(relationColumn(relationField)) + .from(relationTable(relation)) + .innerJoin(modelTable(relationField.relatedModel_!).as(newAlias)) + .on(modelIdColumn(newAlias, relationField.relatedModel_!).eq(relationColumn(relationField.relatedField))) + .where(condition.invert(invertConditionOfSubSelect)) + } + relationFilter.nestedFilter match { case nested: RelationFilter => val condition = inStatementForRelationCondition( @@ -101,15 +111,31 @@ trait FilterConditionBuilder extends BuilderBase { .select(relationColumn(relationField)) .from(relationTable(relation)) .where(condition.invert(invertConditionOfSubSelect)) - + case nested: ScalarFilter => + if (nested.field.isId) { + val condition = nested.condition match { + case Equals(NullGCValue) => field(relationColumn(relationField.relatedField)).isNull + case Equals(_) => field(relationColumn(relationField.relatedField)).equal(placeHolder) + case NotEquals(NullGCValue) => field(relationColumn(relationField.relatedField)).isNotNull + case NotEquals(_) => field(relationColumn(relationField.relatedField)).notEqual(placeHolder) + case In(Vector(NullGCValue)) => field(relationColumn(relationField.relatedField)).isNull + case In(values) => field(relationColumn(relationField.relatedField)).in(Vector.fill(values.length) { + placeHolder + }: _*) + case NotIn(Vector(NullGCValue)) => field(relationColumn(relationField.relatedField)).isNotNull + case NotIn(values) => field(relationColumn(relationField.relatedField)).notIn(Vector.fill(values.length) { + placeHolder + }: _*) + } + sql + .select(relationColumn(relationField)) + .from(relationTable(relation)) + .where(condition) + } + else + getNestedNonRelationalQuery(nested) case nested => - val condition = buildConditionForFilter(nested, newAlias) - sql - .select(relationColumn(relationField)) - .from(relationTable(relation)) - .innerJoin(modelTable(relationField.relatedModel_!).as(newAlias)) - .on(modelIdColumn(newAlias, relationField.relatedModel_!).eq(relationColumn(relationField.relatedField))) - .where(condition.invert(invertConditionOfSubSelect)) + getNestedNonRelationalQuery(nested) } } From a25047eab8d609e8ab684eb305f009c67e8743e0 Mon Sep 17 00:00:00 2001 From: Julien Date: Thu, 23 Jan 2020 11:02:43 +0100 Subject: [PATCH 2/2] fix(connector-jdbc): invert condition on every parent condition --- .../database/FilterConditionBuilder.scala | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/server/connectors/api-connector-jdbc/src/main/scala/com/prisma/api/connector/jdbc/database/FilterConditionBuilder.scala b/server/connectors/api-connector-jdbc/src/main/scala/com/prisma/api/connector/jdbc/database/FilterConditionBuilder.scala index f512886c6b..b2ebdd9a03 100644 --- a/server/connectors/api-connector-jdbc/src/main/scala/com/prisma/api/connector/jdbc/database/FilterConditionBuilder.scala +++ b/server/connectors/api-connector-jdbc/src/main/scala/com/prisma/api/connector/jdbc/database/FilterConditionBuilder.scala @@ -100,6 +100,43 @@ trait FilterConditionBuilder extends BuilderBase { .where(condition.invert(invertConditionOfSubSelect)) } + def getIDNullCondition = { + relationFilter.condition match { + case EveryRelatedNode => field(relationColumn(relationField.relatedField)).isNotNull + case AtLeastOneRelatedNode | NoRelatedNode | ToOneRelatedNode => field(relationColumn(relationField.relatedField)).isNull + } + } + + def getIDNotNullCondition = { + relationFilter.condition match { + case EveryRelatedNode => field(relationColumn(relationField.relatedField)).isNull + case AtLeastOneRelatedNode | NoRelatedNode | ToOneRelatedNode => field(relationColumn(relationField.relatedField)).isNotNull + } + } + + def getNestedIDCondition(nestedCondition: ScalarCondition): Condition = { + nestedCondition match { + case Contains(_) => field(relationColumn(relationField.relatedField)).contains(placeHolder) + case NotContains(_) => field(relationColumn(relationField.relatedField)).notContains(placeHolder) + case StartsWith(_) => field(relationColumn(relationField.relatedField)).startsWith(placeHolder) + case NotStartsWith(_) => field(relationColumn(relationField.relatedField)).startsWith(placeHolder).not() + case EndsWith(_) => field(relationColumn(relationField.relatedField)).endsWith(placeHolder) + case NotEndsWith(_) => field(relationColumn(relationField.relatedField)).endsWith(placeHolder).not() + case LessThan(_) => field(relationColumn(relationField.relatedField)).lessThan(placeHolder) + case GreaterThan(_) => field(relationColumn(relationField.relatedField)).greaterThan(placeHolder) + case LessThanOrEquals(_) => field(relationColumn(relationField.relatedField)).lessOrEqual(placeHolder) + case GreaterThanOrEquals(_) => field(relationColumn(relationField.relatedField)).greaterOrEqual(placeHolder) + case NotEquals(NullGCValue) => getIDNotNullCondition + case NotEquals(_) => field(relationColumn(relationField.relatedField)).notEqual(placeHolder) + case Equals(NullGCValue) => getIDNullCondition + case Equals(_) => field(relationColumn(relationField.relatedField)).equal(placeHolder) + case In(Vector(NullGCValue)) => getIDNullCondition + case NotIn(Vector(NullGCValue)) => getIDNotNullCondition + case In(values) => field(relationColumn(relationField.relatedField)).in(Vector.fill(values.length) { placeHolder }: _*) + case NotIn(values) => field(relationColumn(relationField.relatedField)).notIn(Vector.fill(values.length) { placeHolder }: _*) + } + } + relationFilter.nestedFilter match { case nested: RelationFilter => val condition = inStatementForRelationCondition( @@ -113,24 +150,10 @@ trait FilterConditionBuilder extends BuilderBase { .where(condition.invert(invertConditionOfSubSelect)) case nested: ScalarFilter => if (nested.field.isId) { - val condition = nested.condition match { - case Equals(NullGCValue) => field(relationColumn(relationField.relatedField)).isNull - case Equals(_) => field(relationColumn(relationField.relatedField)).equal(placeHolder) - case NotEquals(NullGCValue) => field(relationColumn(relationField.relatedField)).isNotNull - case NotEquals(_) => field(relationColumn(relationField.relatedField)).notEqual(placeHolder) - case In(Vector(NullGCValue)) => field(relationColumn(relationField.relatedField)).isNull - case In(values) => field(relationColumn(relationField.relatedField)).in(Vector.fill(values.length) { - placeHolder - }: _*) - case NotIn(Vector(NullGCValue)) => field(relationColumn(relationField.relatedField)).isNotNull - case NotIn(values) => field(relationColumn(relationField.relatedField)).notIn(Vector.fill(values.length) { - placeHolder - }: _*) - } sql .select(relationColumn(relationField)) .from(relationTable(relation)) - .where(condition) + .where(getNestedIDCondition(nested.condition)) } else getNestedNonRelationalQuery(nested)