diff --git a/controlplane/src/core/repositories/FeatureFlagRepository.ts b/controlplane/src/core/repositories/FeatureFlagRepository.ts index 66c19210ae..05b7b044c0 100644 --- a/controlplane/src/core/repositories/FeatureFlagRepository.ts +++ b/controlplane/src/core/repositories/FeatureFlagRepository.ts @@ -1,8 +1,9 @@ import { Subgraph } from '@wundergraph/composition'; import { joinLabel, splitLabel } from '@wundergraph/cosmo-shared'; -import { SQL, and, asc, count, eq, getTableName, inArray, like, or, sql } from 'drizzle-orm'; +import { SQL, and, asc, count, eq, inArray, like, or, sql, arrayOverlaps } from 'drizzle-orm'; import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import { FastifyBaseLogger } from 'fastify'; +import { validate as isValidUuid } from 'uuid'; import { parse } from 'graphql'; import * as schema from '../../db/schema.js'; import { @@ -311,12 +312,7 @@ export class FeatureFlagRepository { } if (query) { - conditions.push( - or( - like(schema.targets.name, `%${query}%`), - sql.raw(`${getTableName(schema.subgraphs)}.${schema.subgraphs.id.name}::text like '%${query}%'`), - ), - ); + conditions.push(isValidUuid(query) ? eq(subgraphs.id, query) : like(schema.targets.name, `%${query}%`)); } if (!this.applyRbacConditionsToQuery(rbac, conditions)) { @@ -669,9 +665,13 @@ export class FeatureFlagRepository { const conditions: SQL[] = []; for (const labels of groupedLabels) { - const labelsSQL = labels.map((l) => `"${joinLabel(l)}"`).join(', '); // At least one common label - conditions.push(sql.raw(`labels && '{${labelsSQL}}'`)); + conditions.push( + arrayOverlaps( + featureFlags.labels, + labels.map((l) => joinLabel(l)), + ), + ); } // Only get feature flags that do not have any labels if the label matchers are empty. diff --git a/controlplane/src/core/repositories/FederatedGraphRepository.ts b/controlplane/src/core/repositories/FederatedGraphRepository.ts index eea8a089a9..7418dc4ff8 100644 --- a/controlplane/src/core/repositories/FederatedGraphRepository.ts +++ b/controlplane/src/core/repositories/FederatedGraphRepository.ts @@ -10,6 +10,8 @@ import { import { joinLabel, normalizeURL } from '@wundergraph/cosmo-shared'; import { and, + arrayContains, + arrayOverlaps, asc, desc, eq, @@ -745,10 +747,9 @@ export class FederatedGraphRepository { not( // We created a GIN index on the label_matcher column, so we can look up // very quickly if the label matcher matches the given subgraph labels. - sql.raw( - `${targetLabelMatchers.labelMatcher.name} && ARRAY[${uniqueLabels.map( - (ul) => "'" + joinLabel(ul) + "'", - )}]`, + arrayOverlaps( + targetLabelMatchers.labelMatcher, + uniqueLabels.map((ul) => joinLabel(ul)), ), ), ), diff --git a/controlplane/src/core/repositories/SubgraphRepository.ts b/controlplane/src/core/repositories/SubgraphRepository.ts index 60ab3815a8..755db8c5b6 100644 --- a/controlplane/src/core/repositories/SubgraphRepository.ts +++ b/controlplane/src/core/repositories/SubgraphRepository.ts @@ -9,7 +9,8 @@ import { } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb'; import { joinLabel, normalizeURL, splitLabel } from '@wundergraph/cosmo-shared'; import { addDays } from 'date-fns'; -import { and, asc, count, desc, eq, getTableName, gt, inArray, like, lt, notInArray, or, SQL, sql } from 'drizzle-orm'; +import { and, arrayOverlaps, asc, count, desc, eq, gt, inArray, like, lt, notInArray, or, SQL } from 'drizzle-orm'; +import { validate as isValidUuid } from 'uuid'; import { PostgresJsDatabase } from 'drizzle-orm/postgres-js'; import { FastifyBaseLogger } from 'fastify'; import { GraphQLSchema } from 'graphql'; @@ -698,10 +699,7 @@ export class SubgraphRepository { if (opts.query) { conditions.push( - or( - like(schema.targets.name, `%${opts.query}%`), - sql.raw(`${getTableName(schema.subgraphs)}.${schema.subgraphs.id.name}::text like '%${opts.query}%'`), - ), + isValidUuid(opts.query) ? eq(schema.subgraphs.id, opts.query) : like(schema.targets.name, `%${opts.query}%`), ); } @@ -760,10 +758,7 @@ export class SubgraphRepository { if (opts.query) { conditions.push( - or( - like(schema.targets.name, `%${opts.query}%`), - sql.raw(`${getTableName(schema.subgraphs)}.${schema.subgraphs.id.name}::text like '%${opts.query}%'`), - ), + isValidUuid(opts.query) ? eq(schema.subgraphs.id, opts.query) : like(schema.targets.name, `%${opts.query}%`), ); } @@ -1394,9 +1389,13 @@ export class SubgraphRepository { const conditions: SQL[] = []; for (const labels of groupedLabels) { - const labelsSQL = labels.map((l) => `"${joinLabel(l)}"`).join(', '); // At least one common label - conditions.push(sql.raw(`labels && '{${labelsSQL}}'`)); + conditions.push( + arrayOverlaps( + targets.labels, + labels.map((l) => joinLabel(l)), + ), + ); } // Only get subgraphs that do not have any labels if the label matchers are empty.