From 676058bbbdf47ce79c4b699a3638ea1ec4604bd3 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 23 Sep 2024 17:16:34 +0100 Subject: [PATCH] Updates to limit the response of JSON_ARRAYAGG in mysql/mariaDB - rather than using a limited sub-query which is dis-allowed in MySQL/MariaDB due to the nature of the correlated sub-query. --- packages/backend-core/src/sql/sql.ts | 29 +++++++++++++--------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/packages/backend-core/src/sql/sql.ts b/packages/backend-core/src/sql/sql.ts index 91b4e124cc..db4ddf180b 100644 --- a/packages/backend-core/src/sql/sql.ts +++ b/packages/backend-core/src/sql/sql.ts @@ -958,22 +958,9 @@ class InternalBuilder { const primaryKey = `${toAlias}.${toPrimary || toKey}` let subQuery: Knex.QueryBuilder = knex .from(toTableWithSchema) - .limit(getRelationshipLimit()) // add sorting to get consistent order .orderBy(primaryKey) - const addCorrelatedWhere = ( - query: Knex.QueryBuilder, - column1: string, - column2: string - ) => { - return query.where( - column1, - "=", - knex.raw(this.quotedIdentifier(column2)) - ) - } - const isManyToMany = throughTable && toPrimary && fromPrimary let correlatedTo = isManyToMany ? `${throughAlias}.${fromKey}` @@ -992,10 +979,15 @@ class InternalBuilder { }) } - subQuery = addCorrelatedWhere(subQuery, correlatedTo, correlatedFrom) + // add the correlation to the overall query + subQuery = subQuery.where( + correlatedTo, + "=", + knex.raw(this.quotedIdentifier(correlatedFrom)) + ) const standardWrap = (select: string): Knex.QueryBuilder => { - subQuery = subQuery.select(`${toAlias}.*`) + subQuery = subQuery.select(`${toAlias}.*`).limit(getRelationshipLimit()) // @ts-ignore - the from alias syntax isn't in Knex typing return knex.select(knex.raw(select)).from({ [toAlias]: subQuery, @@ -1016,7 +1008,12 @@ class InternalBuilder { ) break case SqlClient.MY_SQL: - wrapperQuery = knex.raw(`json_arrayagg(json_object(${fieldList}))`) + // can't use the standard wrap due to correlated sub-query limitations in MariaDB + wrapperQuery = subQuery.select( + knex.raw( + `json_arrayagg(json_object(${fieldList}) LIMIT ${getRelationshipLimit()})` + ) + ) break case SqlClient.ORACLE: wrapperQuery = standardWrap(