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 static org.opensearch.sql.data.type.ExprCoreType.STRUCT; | |
10 | ||
11 | import com.google.common.collect.ImmutableMap; | |
12 | import com.google.common.collect.ImmutableMap.Builder; | |
13 | import java.util.Collections; | |
14 | import java.util.List; | |
15 | import java.util.Map; | |
16 | import java.util.Map.Entry; | |
17 | import java.util.Set; | |
18 | import java.util.stream.Collectors; | |
19 | import lombok.EqualsAndHashCode; | |
20 | import lombok.Getter; | |
21 | import lombok.ToString; | |
22 | import org.opensearch.sql.data.model.ExprTupleValue; | |
23 | import org.opensearch.sql.data.model.ExprValue; | |
24 | import org.opensearch.sql.data.model.ExprValueUtils; | |
25 | import org.opensearch.sql.expression.ReferenceExpression; | |
26 | ||
27 | /** | |
28 | * Remove the fields specified in {@link RemoveOperator#removeList} from input. | |
29 | */ | |
30 | @ToString | |
31 | @EqualsAndHashCode(callSuper = false) | |
32 | public class RemoveOperator extends PhysicalPlan { | |
33 | @Getter | |
34 | private final PhysicalPlan input; | |
35 | @Getter | |
36 | private final Set<ReferenceExpression> removeList; | |
37 | @ToString.Exclude | |
38 | @EqualsAndHashCode.Exclude | |
39 | private final Set<String> nameRemoveList; | |
40 | ||
41 | /** | |
42 | * Todo. This is the temporary solution that add the mapping between string and ref. because when | |
43 | * rename the field from input, there we can only get the string field. | |
44 | */ | |
45 | public RemoveOperator(PhysicalPlan input, | |
46 | Set<ReferenceExpression> removeList) { | |
47 | this.input = input; | |
48 | this.removeList = removeList; | |
49 | this.nameRemoveList = | |
50 | removeList.stream().map(ReferenceExpression::getAttr).collect(Collectors.toSet()); | |
51 | } | |
52 | ||
53 | @Override | |
54 | public <R, C> R accept(PhysicalPlanNodeVisitor<R, C> visitor, C context) { | |
55 |
1
1. accept : replaced return value with null for org/opensearch/sql/planner/physical/RemoveOperator::accept → KILLED |
return visitor.visitRemove(this, context); |
56 | } | |
57 | ||
58 | @Override | |
59 | public List<PhysicalPlan> getChild() { | |
60 |
1
1. getChild : replaced return value with Collections.emptyList for org/opensearch/sql/planner/physical/RemoveOperator::getChild → KILLED |
return Collections.singletonList(input); |
61 | } | |
62 | ||
63 | @Override | |
64 | public boolean hasNext() { | |
65 |
2
1. hasNext : replaced boolean return with true for org/opensearch/sql/planner/physical/RemoveOperator::hasNext → TIMED_OUT 2. hasNext : replaced boolean return with false for org/opensearch/sql/planner/physical/RemoveOperator::hasNext → KILLED |
return input.hasNext(); |
66 | } | |
67 | ||
68 | @Override | |
69 | public ExprValue next() { | |
70 | ExprValue inputValue = input.next(); | |
71 |
1
1. next : negated conditional → KILLED |
if (STRUCT == inputValue.type()) { |
72 | ImmutableMap.Builder<String, ExprValue> mapBuilder = new Builder<>(); | |
73 | Map<String, ExprValue> tupleValue = ExprValueUtils.getTupleValue(inputValue); | |
74 | for (Entry<String, ExprValue> valueEntry : tupleValue.entrySet()) { | |
75 |
1
1. next : negated conditional → KILLED |
if (!nameRemoveList.contains(valueEntry.getKey())) { |
76 | mapBuilder.put(valueEntry); | |
77 | } | |
78 | } | |
79 |
1
1. next : replaced return value with null for org/opensearch/sql/planner/physical/RemoveOperator::next → KILLED |
return ExprTupleValue.fromExprValueMap(mapBuilder.build()); |
80 | } else { | |
81 |
1
1. next : replaced return value with null for org/opensearch/sql/planner/physical/RemoveOperator::next → KILLED |
return inputValue; |
82 | } | |
83 | } | |
84 | } | |
Mutations | ||
55 |
1.1 |
|
60 |
1.1 |
|
65 |
1.1 2.2 |
|
71 |
1.1 |
|
75 |
1.1 |
|
79 |
1.1 |
|
81 |
1.1 |