1 | /* | |
2 | * Copyright OpenSearch Contributors | |
3 | * SPDX-License-Identifier: Apache-2.0 | |
4 | */ | |
5 | ||
6 | ||
7 | package org.opensearch.sql.planner.physical; | |
8 | ||
9 | import com.google.common.collect.ImmutableList; | |
10 | import java.util.List; | |
11 | import lombok.EqualsAndHashCode; | |
12 | import lombok.Getter; | |
13 | import lombok.RequiredArgsConstructor; | |
14 | import lombok.ToString; | |
15 | import org.opensearch.sql.data.model.ExprValue; | |
16 | ||
17 | /** | |
18 | * The limit operator sets a window, to and block the rows out of the window | |
19 | * and allow only the result subset within this window to the output. | |
20 | * | |
21 | * <p>The result subset is enframed from original result with {@link LimitOperator#offset} | |
22 | * as the offset and {@link LimitOperator#limit} as the size, thus the output | |
23 | * is the subset of the original result set that has indices from {index + 1} to {index + limit}. | |
24 | * Special cases might occur where the result subset has a size smaller than expected {limit}, | |
25 | * it occurs when the original result set has a size smaller than {index + limit}, | |
26 | * or even not greater than the offset. The latter results in an empty output.</p> | |
27 | */ | |
28 | @RequiredArgsConstructor | |
29 | @Getter | |
30 | @ToString | |
31 | @EqualsAndHashCode(callSuper = false) | |
32 | public class LimitOperator extends PhysicalPlan { | |
33 | private final PhysicalPlan input; | |
34 | private final Integer limit; | |
35 | private final Integer offset; | |
36 | private Integer count = 0; | |
37 | ||
38 | @Override | |
39 | public void open() { | |
40 |
1
1. open : removed call to org/opensearch/sql/planner/physical/PhysicalPlan::open → SURVIVED |
super.open(); |
41 | ||
42 | // skip the leading rows of offset size | |
43 |
3
1. open : changed conditional boundary → KILLED 2. open : negated conditional → KILLED 3. open : negated conditional → KILLED |
while (input.hasNext() && count < offset) { |
44 |
1
1. open : Replaced integer addition with subtraction → KILLED |
count++; |
45 | input.next(); | |
46 | } | |
47 | } | |
48 | ||
49 | @Override | |
50 | public boolean hasNext() { | |
51 |
5
1. hasNext : changed conditional boundary → KILLED 2. hasNext : Replaced integer addition with subtraction → KILLED 3. hasNext : negated conditional → KILLED 4. hasNext : negated conditional → KILLED 5. hasNext : replaced boolean return with true for org/opensearch/sql/planner/physical/LimitOperator::hasNext → KILLED |
return input.hasNext() && count < offset + limit; |
52 | } | |
53 | ||
54 | @Override | |
55 | public ExprValue next() { | |
56 |
1
1. next : Replaced integer addition with subtraction → KILLED |
count++; |
57 |
1
1. next : replaced return value with null for org/opensearch/sql/planner/physical/LimitOperator::next → KILLED |
return input.next(); |
58 | } | |
59 | ||
60 | @Override | |
61 | public <R, C> R accept(PhysicalPlanNodeVisitor<R, C> visitor, C context) { | |
62 |
1
1. accept : replaced return value with null for org/opensearch/sql/planner/physical/LimitOperator::accept → KILLED |
return visitor.visitLimit(this, context); |
63 | } | |
64 | ||
65 | @Override | |
66 | public List<PhysicalPlan> getChild() { | |
67 |
1
1. getChild : replaced return value with Collections.emptyList for org/opensearch/sql/planner/physical/LimitOperator::getChild → KILLED |
return ImmutableList.of(input); |
68 | } | |
69 | ||
70 | } | |
Mutations | ||
40 |
1.1 |
|
43 |
1.1 2.2 3.3 |
|
44 |
1.1 |
|
51 |
1.1 2.2 3.3 4.4 5.5 |
|
56 |
1.1 |
|
57 |
1.1 |
|
62 |
1.1 |
|
67 |
1.1 |