fix: Prevent promotion filtering to exceed psql limits (#13540)
* fix(): Prevent promotion filtering to exceed psql limits * Create sour-rockets-grin.md
This commit is contained in:
committed by
GitHub
parent
aa7ea4d9a6
commit
4736c58da5
5
.changeset/sour-rockets-grin.md
Normal file
5
.changeset/sour-rockets-grin.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@medusajs/promotion": patch
|
||||
---
|
||||
|
||||
fix(): Prevent promotion filtering to exceed psql limits
|
||||
@@ -353,7 +353,7 @@ moduleIntegrationTestRunner({
|
||||
value: 100,
|
||||
target_rules: [
|
||||
{
|
||||
attribute: "product.id",
|
||||
attribute: "items.product.id",
|
||||
operator: "eq",
|
||||
values: ["prod_tshirt0"], // Only applies to product 0
|
||||
},
|
||||
|
||||
@@ -466,7 +466,10 @@ export default class PromotionModuleService
|
||||
|
||||
if (!preventAutoPromotions) {
|
||||
const rulePrefilteringFilters =
|
||||
buildPromotionRuleQueryFilterFromContext(applicationContext)
|
||||
await buildPromotionRuleQueryFilterFromContext(
|
||||
applicationContext,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
let prefilteredAutomaticPromotionIds: string[] = []
|
||||
|
||||
|
||||
@@ -2,11 +2,12 @@ import {
|
||||
ComputeActionContext,
|
||||
ComputeActionItemLine,
|
||||
ComputeActionShippingLine,
|
||||
Context,
|
||||
DAL,
|
||||
PromotionTypes,
|
||||
} from "@medusajs/framework/types"
|
||||
import { flattenObjectToKeyValuePairs } from "@medusajs/framework/utils"
|
||||
import { raw } from "@mikro-orm/postgresql"
|
||||
import { raw, SqlEntityManager } from "@mikro-orm/postgresql"
|
||||
|
||||
/**
|
||||
* Builds a query filter for promotion rules based on the context.
|
||||
@@ -17,9 +18,10 @@ import { raw } from "@mikro-orm/postgresql"
|
||||
* @param context
|
||||
* @returns
|
||||
*/
|
||||
export function buildPromotionRuleQueryFilterFromContext(
|
||||
context: PromotionTypes.ComputeActionContext
|
||||
): DAL.FilterQuery<any> | null {
|
||||
export async function buildPromotionRuleQueryFilterFromContext(
|
||||
context: PromotionTypes.ComputeActionContext,
|
||||
sharedContext: Context
|
||||
): Promise<DAL.FilterQuery<any> | null> {
|
||||
const {
|
||||
items = [],
|
||||
shipping_methods: shippingMethods = [],
|
||||
@@ -67,6 +69,33 @@ export function buildPromotionRuleQueryFilterFromContext(
|
||||
})
|
||||
})
|
||||
|
||||
// count the number of attributes in the map
|
||||
const numberOfAttributes = attributeValueMap.size
|
||||
if (numberOfAttributes > 10) {
|
||||
const manager = (sharedContext.transactionManager ??
|
||||
sharedContext.manager) as SqlEntityManager
|
||||
const knex = manager.getKnex()
|
||||
|
||||
const { rows } = await knex.raw(
|
||||
`
|
||||
SELECT DISTINCT attribute
|
||||
FROM promotion_rule
|
||||
WHERE deleted_at IS NULL
|
||||
`
|
||||
)
|
||||
|
||||
const dbAvailableAttributes = new Set(
|
||||
rows.map(({ attribute }) => attribute)
|
||||
)
|
||||
|
||||
// update the attribute in the map to remove the one that are not in the db
|
||||
attributeValueMap.forEach((valueSet, attribute) => {
|
||||
if (!dbAvailableAttributes.has(attribute)) {
|
||||
attributeValueMap.delete(attribute)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Build conditions for a NOT EXISTS subquery to exclude promotions with unsatisfiable rules
|
||||
const sqlConditions: string[] = []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user