Skip to content
This repository was archived by the owner on Mar 2, 2026. It is now read-only.

Commit 4b81052

Browse files
committed
allow multiple logical_min/max inputs
1 parent d1e3da8 commit 4b81052

3 files changed

Lines changed: 82 additions & 22 deletions

File tree

google/cloud/firestore_v1/pipeline_expressions.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ def sqrt(self) -> "Expression":
396396
return Function("sqrt", [self])
397397

398398
@expose_as_static
399-
def logical_maximum(self, other: Expression | CONSTANT_TYPE) -> "Expression":
399+
def logical_maximum(self, *others: Expression | CONSTANT_TYPE) -> "Expression":
400400
"""Creates an expression that returns the larger value between this expression
401401
and another expression or constant, based on Firestore's value type ordering.
402402
@@ -406,23 +406,23 @@ def logical_maximum(self, other: Expression | CONSTANT_TYPE) -> "Expression":
406406
Example:
407407
>>> # Returns the larger value between the 'discount' field and the 'cap' field.
408408
>>> Field.of("discount").logical_maximum(Field.of("cap"))
409-
>>> # Returns the larger value between the 'value' field and 10.
410-
>>> Field.of("value").logical_maximum(10)
409+
>>> # Returns the larger value between the 'value' field and some ints
410+
>>> Field.of("value").logical_maximum(10, 20, 30)
411411
412412
Args:
413-
other: The other expression or constant value to compare with.
413+
others: The other expression or constant values to compare with.
414414
415415
Returns:
416416
A new `Expression` representing the logical maximum operation.
417417
"""
418418
return Function(
419419
"maximum",
420-
[self, self._cast_to_expr_or_convert_to_constant(other)],
420+
[self] + [self._cast_to_expr_or_convert_to_constant(o) for o in others],
421421
infix_name_override="logical_maximum",
422422
)
423423

424424
@expose_as_static
425-
def logical_minimum(self, other: Expression | CONSTANT_TYPE) -> "Expression":
425+
def logical_minimum(self, *others: Expression | CONSTANT_TYPE) -> "Expression":
426426
"""Creates an expression that returns the smaller value between this expression
427427
and another expression or constant, based on Firestore's value type ordering.
428428
@@ -432,18 +432,18 @@ def logical_minimum(self, other: Expression | CONSTANT_TYPE) -> "Expression":
432432
Example:
433433
>>> # Returns the smaller value between the 'discount' field and the 'floor' field.
434434
>>> Field.of("discount").logical_minimum(Field.of("floor"))
435-
>>> # Returns the smaller value between the 'value' field and 10.
436-
>>> Field.of("value").logical_minimum(10)
435+
>>> # Returns the smaller value between the 'value' field and some ints
436+
>>> Field.of("value").logical_minimum(10, 20, 30)
437437
438438
Args:
439-
other: The other expression or constant value to compare with.
439+
others: The other expression or constant values to compare with.
440440
441441
Returns:
442442
A new `Expression` representing the logical minimum operation.
443443
"""
444444
return Function(
445445
"minimum",
446-
[self, self._cast_to_expr_or_convert_to_constant(other)],
446+
[self] + [self._cast_to_expr_or_convert_to_constant(o) for o in others],
447447
infix_name_override="logical_minimum",
448448
)
449449

tests/system/pipeline_e2e/logical.yaml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,64 @@ tests:
505505
- doubleValue: 4.5
506506
name: maximum
507507
name: select
508+
- description: testLogicalMinMaxWithMultipleInputs
509+
pipeline:
510+
- Collection: books
511+
- Where:
512+
- Function.equal:
513+
- Field: author
514+
- Constant: Douglas Adams
515+
- Select:
516+
- AliasedExpression:
517+
- Function.logical_maximum:
518+
- Field: rating
519+
- Constant: 4.5
520+
- Constant: 3.0
521+
- Constant: 5.0
522+
- "max_rating"
523+
- AliasedExpression:
524+
- Function.logical_minimum:
525+
- Field: published
526+
- Constant: 1900
527+
- Constant: 2000
528+
- Constant: 1984
529+
- "min_published"
530+
assert_results:
531+
- max_rating: 5.0
532+
min_published: 1900
533+
assert_proto:
534+
pipeline:
535+
stages:
536+
- args:
537+
- referenceValue: /books
538+
name: collection
539+
- args:
540+
- functionValue:
541+
args:
542+
- fieldReferenceValue: author
543+
- stringValue: Douglas Adams
544+
name: equal
545+
name: where
546+
- args:
547+
- mapValue:
548+
fields:
549+
min_published:
550+
functionValue:
551+
args:
552+
- fieldReferenceValue: published
553+
- integerValue: '1900'
554+
- integerValue: '2000'
555+
- integerValue: '1984'
556+
name: minimum
557+
max_rating:
558+
functionValue:
559+
args:
560+
- fieldReferenceValue: rating
561+
- doubleValue: 4.5
562+
- doubleValue: 3.0
563+
- doubleValue: 5.0
564+
name: maximum
565+
name: select
508566
- description: testGreaterThanOrEqual
509567
pipeline:
510568
- Collection: books

tests/unit/v1/test_pipeline_expressions.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,23 +1024,25 @@ def test_divide(self):
10241024
assert infix_instance == instance
10251025

10261026
def test_logical_maximum(self):
1027-
arg1 = self._make_arg("Left")
1028-
arg2 = self._make_arg("Right")
1029-
instance = Expression.logical_maximum(arg1, arg2)
1027+
arg1 = self._make_arg("A1")
1028+
arg2 = self._make_arg("A2")
1029+
arg3 = self._make_arg("A3")
1030+
instance = Expression.logical_maximum(arg1, arg2, arg3)
10301031
assert instance.name == "maximum"
1031-
assert instance.params == [arg1, arg2]
1032-
assert repr(instance) == "Left.logical_maximum(Right)"
1033-
infix_instance = arg1.logical_maximum(arg2)
1032+
assert instance.params == [arg1, arg2, arg3]
1033+
assert repr(instance) == "A1.logical_maximum(A2, A3)"
1034+
infix_instance = arg1.logical_maximum(arg2, arg3)
10341035
assert infix_instance == instance
10351036

10361037
def test_logical_minimum(self):
1037-
arg1 = self._make_arg("Left")
1038-
arg2 = self._make_arg("Right")
1039-
instance = Expression.logical_minimum(arg1, arg2)
1038+
arg1 = self._make_arg("A1")
1039+
arg2 = self._make_arg("A2")
1040+
arg3 = self._make_arg("A3")
1041+
instance = Expression.logical_minimum(arg1, arg2, arg3)
10401042
assert instance.name == "minimum"
1041-
assert instance.params == [arg1, arg2]
1042-
assert repr(instance) == "Left.logical_minimum(Right)"
1043-
infix_instance = arg1.logical_minimum(arg2)
1043+
assert instance.params == [arg1, arg2, arg3]
1044+
assert repr(instance) == "A1.logical_minimum(A2, A3)"
1045+
infix_instance = arg1.logical_minimum(arg2, arg3)
10441046
assert infix_instance == instance
10451047

10461048
def test_to_lower(self):

0 commit comments

Comments
 (0)