diff --git a/packages/backend-core/src/sql/sql.ts b/packages/backend-core/src/sql/sql.ts index 9b6819d433..e6738d4b36 100644 --- a/packages/backend-core/src/sql/sql.ts +++ b/packages/backend-core/src/sql/sql.ts @@ -337,6 +337,11 @@ class InternalBuilder { return filters } + addJoinFieldCheck(query: Knex.QueryBuilder, relationship: RelationshipsJson) { + const document = relationship.from?.split(".")[0] || "" + return query.andWhere(`${document}.fieldName`, "=", relationship.column) + } + addRelationshipForFilter( query: Knex.QueryBuilder, filterKey: string, @@ -363,8 +368,6 @@ class InternalBuilder { let subQuery = mainKnex .select(mainKnex.raw(1)) .from({ [toAlias]: relatedTableName }) - // relationships should never have more than the base limit - .limit(getBaseLimit()) let mainTableRelatesTo = toAlias if (relationship.through) { const throughAlias = @@ -375,12 +378,15 @@ class InternalBuilder { }) subQuery = subQuery.innerJoin(throughTable, function () { // @ts-ignore - this.orOn( + this.on( `${toAlias}.${relationship.toPrimary}`, "=", `${throughAlias}.${relationship.to}` ) }) + if (this.client === SqlClient.SQL_LITE) { + subQuery = this.addJoinFieldCheck(subQuery, relationship) + } mainTableRelatesTo = throughAlias } // "join" to the main table, making sure the ID matches that of the main @@ -907,7 +913,7 @@ class InternalBuilder { default: throw new Error(`JSON relationships not implement for ${this.client}`) } - const subQuery = this.knex + let subQuery = this.knex .select(rawJsonArray) .from(toTableWithSchema) .join(throughTableWithSchema, function () { @@ -918,6 +924,12 @@ class InternalBuilder { "=", this.knex.raw(this.quotedIdentifier(`${fromAlias}.${fromPrimary}`)) ) + // relationships should never have more than the base limit + .limit(getBaseLimit()) + // need to check the junction table document is to the right column + if (this.client === SqlClient.SQL_LITE) { + subQuery = this.addJoinFieldCheck(subQuery, relationship) + } query = query.select({ [relationship.column]: subQuery }) } return query diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index bac9b6f774..44fe18d0ef 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -2687,7 +2687,8 @@ describe.each([ }) }) - isSql && + // TODO: when all SQL databases use the same mechanism - remove this test, new relationship system doesn't have this problem + !isInternal && describe("pagination edge case with relationships", () => { let mainRows: Row[] = [] diff --git a/packages/server/src/utilities/rowProcessor/index.ts b/packages/server/src/utilities/rowProcessor/index.ts index 795f6970ab..6028b2d248 100644 --- a/packages/server/src/utilities/rowProcessor/index.ts +++ b/packages/server/src/utilities/rowProcessor/index.ts @@ -336,6 +336,13 @@ export async function outputProcessing( row[property] = `${hours}:${minutes}:${seconds}` } } + } else if (column.type === FieldType.LINK) { + for (let row of enriched) { + // if relationship is empty - remove the array, this has been part of the API for some time + if (Array.isArray(row[property]) && row[property].length === 0) { + delete row[property] + } + } } }