* Helper to combine where predicates with common logic for AND/OR operations
(
predicates: Array<BasicExpression<boolean>>,
operation: `and` | `or`,
simplifyFn: (
preds: Array<BasicExpression<boolean>>,
) => BasicExpression<boolean> | null,
)
| 204 | * Helper to combine where predicates with common logic for AND/OR operations |
| 205 | */ |
| 206 | function combineWherePredicates( |
| 207 | predicates: Array<BasicExpression<boolean>>, |
| 208 | operation: `and` | `or`, |
| 209 | simplifyFn: ( |
| 210 | preds: Array<BasicExpression<boolean>>, |
| 211 | ) => BasicExpression<boolean> | null, |
| 212 | ): BasicExpression<boolean> { |
| 213 | const emptyValue = operation === `and` ? true : false |
| 214 | const identityValue = operation === `and` ? true : false |
| 215 | |
| 216 | if (predicates.length === 0) { |
| 217 | return { type: `val`, value: emptyValue } as BasicExpression<boolean> |
| 218 | } |
| 219 | |
| 220 | if (predicates.length === 1) { |
| 221 | return predicates[0]! |
| 222 | } |
| 223 | |
| 224 | // Flatten nested expressions of the same operation |
| 225 | const flatPredicates: Array<BasicExpression<boolean>> = [] |
| 226 | for (const pred of predicates) { |
| 227 | if (pred.type === `func` && pred.name === operation) { |
| 228 | flatPredicates.push(...pred.args) |
| 229 | } else { |
| 230 | flatPredicates.push(pred) |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | // Group predicates by field for simplification |
| 235 | const grouped = groupPredicatesByField(flatPredicates) |
| 236 | |
| 237 | // Simplify each group |
| 238 | const simplified: Array<BasicExpression<boolean>> = [] |
| 239 | for (const [field, preds] of grouped.entries()) { |
| 240 | if (field === null) { |
| 241 | // Complex predicates that we can't group by field |
| 242 | simplified.push(...preds) |
| 243 | } else { |
| 244 | // Try to simplify same-field predicates |
| 245 | const result = simplifyFn(preds) |
| 246 | |
| 247 | // For intersection: check for empty set (contradiction) |
| 248 | if ( |
| 249 | operation === `and` && |
| 250 | result && |
| 251 | result.type === `val` && |
| 252 | result.value === false |
| 253 | ) { |
| 254 | // Intersection is empty (conflicting constraints) - entire AND is false |
| 255 | return { type: `val`, value: false } as BasicExpression<boolean> |
| 256 | } |
| 257 | |
| 258 | // For union: result may be null if simplification failed |
| 259 | if (result) { |
| 260 | simplified.push(result) |
| 261 | } |
| 262 | } |
| 263 | } |
no test coverage detected