* Optimizes simple comparison expressions (eq, gt, gte, lt, lte)
( expression: BasicExpression, collection: CollectionLike<T, TKey>, )
| 474 | * Optimizes simple comparison expressions (eq, gt, gte, lt, lte) |
| 475 | */ |
| 476 | function optimizeSimpleComparison< |
| 477 | T extends object, |
| 478 | TKey extends string | number, |
| 479 | >( |
| 480 | expression: BasicExpression, |
| 481 | collection: CollectionLike<T, TKey>, |
| 482 | ): OptimizationResult<TKey> { |
| 483 | if (expression.type !== `func` || expression.args.length !== 2) { |
| 484 | return { canOptimize: false, matchingKeys: new Set(), isExact: false } |
| 485 | } |
| 486 | |
| 487 | const leftArg = expression.args[0]! |
| 488 | const rightArg = expression.args[1]! |
| 489 | |
| 490 | // Check both directions: field op value AND value op field |
| 491 | let fieldArg: BasicExpression | null = null |
| 492 | let valueArg: BasicExpression | null = null |
| 493 | let operation = expression.name as `eq` | `gt` | `gte` | `lt` | `lte` |
| 494 | |
| 495 | if (leftArg.type === `ref` && rightArg.type === `val`) { |
| 496 | // field op value |
| 497 | fieldArg = leftArg |
| 498 | valueArg = rightArg |
| 499 | } else if (leftArg.type === `val` && rightArg.type === `ref`) { |
| 500 | // value op field - need to flip the operation |
| 501 | fieldArg = rightArg |
| 502 | valueArg = leftArg |
| 503 | |
| 504 | // Flip the operation for reverse comparison |
| 505 | switch (operation) { |
| 506 | case `gt`: |
| 507 | operation = `lt` |
| 508 | break |
| 509 | case `gte`: |
| 510 | operation = `lte` |
| 511 | break |
| 512 | case `lt`: |
| 513 | operation = `gt` |
| 514 | break |
| 515 | case `lte`: |
| 516 | operation = `gte` |
| 517 | break |
| 518 | // eq stays the same |
| 519 | } |
| 520 | } |
| 521 | |
| 522 | if (fieldArg && valueArg) { |
| 523 | const fieldPath = (fieldArg as any).path |
| 524 | const index = findIndexForField(collection, fieldPath) |
| 525 | |
| 526 | if (index) { |
| 527 | const queryValue = (valueArg as any).value |
| 528 | |
| 529 | // Map operation to IndexOperation enum |
| 530 | const indexOperation = operation as IndexOperation |
| 531 | |
| 532 | // Check if the index supports this operation |
| 533 | if (!index.supports(indexOperation)) { |
no test coverage detected