* Helper function to compute difference for same-field predicates
( fromPred: Func, subtractPred: Func, )
| 407 | * Helper function to compute difference for same-field predicates |
| 408 | */ |
| 409 | function minusSameFieldPredicates( |
| 410 | fromPred: Func, |
| 411 | subtractPred: Func, |
| 412 | ): BasicExpression<boolean> | null { |
| 413 | // Extract field information |
| 414 | const fromField = |
| 415 | extractComparisonField(fromPred) || |
| 416 | extractEqualityField(fromPred) || |
| 417 | extractInField(fromPred) |
| 418 | const subtractField = |
| 419 | extractComparisonField(subtractPred) || |
| 420 | extractEqualityField(subtractPred) || |
| 421 | extractInField(subtractPred) |
| 422 | |
| 423 | // Must be on the same field |
| 424 | if ( |
| 425 | !fromField || |
| 426 | !subtractField || |
| 427 | !areRefsEqual(fromField.ref, subtractField.ref) |
| 428 | ) { |
| 429 | return null |
| 430 | } |
| 431 | |
| 432 | // Handle IN minus IN: status IN [A,B,C,D] - status IN [B,C] = status IN [A,D] |
| 433 | if (fromPred.name === `in` && subtractPred.name === `in`) { |
| 434 | const fromInField = fromField as InField |
| 435 | const subtractInField = subtractField as InField |
| 436 | |
| 437 | // Filter out values that are in the subtract set |
| 438 | const remainingValues = fromInField.values.filter( |
| 439 | (v) => |
| 440 | !arrayIncludesWithSet( |
| 441 | subtractInField.values, |
| 442 | v, |
| 443 | subtractInField.primitiveSet ?? null, |
| 444 | subtractInField.areAllPrimitives, |
| 445 | ), |
| 446 | ) |
| 447 | |
| 448 | if (remainingValues.length === 0) { |
| 449 | return { type: `val`, value: false } as BasicExpression<boolean> |
| 450 | } |
| 451 | |
| 452 | if (remainingValues.length === 1) { |
| 453 | return { |
| 454 | type: `func`, |
| 455 | name: `eq`, |
| 456 | args: [fromField.ref, { type: `val`, value: remainingValues[0] }], |
| 457 | } as BasicExpression<boolean> |
| 458 | } |
| 459 | |
| 460 | return { |
| 461 | type: `func`, |
| 462 | name: `in`, |
| 463 | args: [fromField.ref, { type: `val`, value: remainingValues }], |
| 464 | } as BasicExpression<boolean> |
| 465 | } |
| 466 |
no test coverage detected