Skip to content

Commit 3f7c6a6

Browse files
committed
Refactor CompareIpFunction to use SqlKind directly
Signed-off-by: Yuanchun Shen <yuanchu@amazon.com>
1 parent 93c147b commit 3f7c6a6

2 files changed

Lines changed: 62 additions & 61 deletions

File tree

core/src/main/java/org/opensearch/sql/expression/function/PPLBuiltinOperators.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,23 @@ private static Expression invokeCalciteImplementor(
392392
return (Expression) method.invoke(rexCallImplementor, translator, call, List.of(field));
393393
}
394394

395+
/**
396+
* Creates a lazy supplier for looking up a SQL operator by name.
397+
*
398+
* <p>This method enables operators to reference each other, even when they have circular
399+
* dependencies. Instead of looking up the operator immediately, it returns a supplier that will
400+
* perform the lookup only when needed.
401+
*
402+
* <p>For example, {@code LESS_IP} needs to reference {@code GREATER_IP} as its reverse, and vice
403+
* versa. Using this lazy approach, both can be defined before either is used.
404+
*
405+
* @param name The name of the operator to look up
406+
* @return A supplier that will look up the operator when called
407+
*/
395408
private static Supplier<SqlOperator> lookupOperator(String name) {
396409
return () -> {
397410
AtomicReference<SqlOperator> ref = new AtomicReference<>();
398-
INSTANCE.get().lookUpOperators(name, false, ref::set);
411+
instance().lookUpOperators(name, false, ref::set);
399412
return ref.get();
400413
};
401414
}

core/src/main/java/org/opensearch/sql/expression/function/udf/ip/CompareIpFunction.java

Lines changed: 48 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.opensearch.sql.expression.function.udf.ip;
77

88
import java.util.List;
9+
import java.util.Locale;
910
import java.util.function.Supplier;
1011
import org.apache.calcite.adapter.enumerable.NotNullImplementor;
1112
import org.apache.calcite.adapter.enumerable.NullPolicy;
@@ -36,80 +37,75 @@
3637
* </ul>
3738
*/
3839
public class CompareIpFunction extends ImplementorUDF {
40+
private final SqlKind kind;
3941
private Supplier<SqlOperator> reverse;
4042

41-
private CompareIpFunction(ComparisonType comparisonType) {
42-
super(new CompareImplementor(comparisonType), NullPolicy.ANY);
43-
reverse = null;
43+
private CompareIpFunction(SqlKind kind) {
44+
super(new CompareImplementor(kind), NullPolicy.ANY);
45+
this.kind = kind;
46+
// Will be set later
47+
this.reverse = null;
4448
}
4549

4650
@Override
4751
public SqlSyntax getSqlSyntax() {
4852
return SqlSyntax.BINARY;
4953
}
5054

51-
public static CompareIpFunction less() {
52-
return new CompareIpFunction(ComparisonType.LESS) {
53-
@Override
54-
public SqlKind getKind() {
55-
return SqlKind.LESS_THAN;
56-
}
57-
};
55+
@Override
56+
public SqlKind getKind() {
57+
return kind;
5858
}
5959

6060
@Override
6161
public Supplier<SqlOperator> getReverse() {
6262
return reverse;
6363
}
6464

65+
/**
66+
* Sets the reverse operator supplier for this comparison function.
67+
*
68+
* <p>This method is used to establish the reversed relationship between comparison operators
69+
* (e.g., "less than" and "greater than"). When the query optimizer normalizes expressions, it may
70+
* need to transform "b > a" to "a < b".
71+
*
72+
* <p>E.g. in the {@code hashCode} method of {@link org.apache.calcite.rex.RexNormalize}#L115, it
73+
* always converts <i>B [comparator] A</i> to <i>A [reverse_comparator] B</i> if the ordinal of
74+
* the reverse of the comparator is smaller.
75+
*
76+
* <p>IP comparison functions use this to inform the optimizer that ip_less_than is the reverse of
77+
* ip_greater_than, allowing for proper query normalization.
78+
*
79+
* @param supplier The supplier that provides the reverse SQL operator
80+
* @return This CompareIpFunction instance for method chaining
81+
*/
6582
public CompareIpFunction withReverse(Supplier<SqlOperator> supplier) {
6683
this.reverse = supplier;
6784
return this;
6885
}
6986

87+
public static CompareIpFunction less() {
88+
return new CompareIpFunction(SqlKind.LESS_THAN);
89+
}
90+
7091
public static CompareIpFunction greater() {
71-
return new CompareIpFunction(ComparisonType.GREATER) {
72-
@Override
73-
public SqlKind getKind() {
74-
return SqlKind.GREATER_THAN;
75-
}
76-
};
92+
return new CompareIpFunction(SqlKind.GREATER_THAN);
7793
}
7894

7995
public static CompareIpFunction lessOrEquals() {
80-
return new CompareIpFunction(ComparisonType.LESS_OR_EQUAL) {
81-
@Override
82-
public SqlKind getKind() {
83-
return SqlKind.LESS_THAN_OR_EQUAL;
84-
}
85-
};
96+
return new CompareIpFunction(SqlKind.LESS_THAN_OR_EQUAL);
8697
}
8798

8899
public static CompareIpFunction greaterOrEquals() {
89-
return new CompareIpFunction(ComparisonType.GREATER_OR_EQUAL) {
90-
@Override
91-
public SqlKind getKind() {
92-
return SqlKind.GREATER_THAN_OR_EQUAL;
93-
}
94-
};
100+
return new CompareIpFunction(SqlKind.GREATER_THAN_OR_EQUAL);
95101
}
96102

97103
public static CompareIpFunction equals() {
98-
return new CompareIpFunction(ComparisonType.EQUALS) {
99-
@Override
100-
public SqlKind getKind() {
101-
return SqlKind.EQUALS;
102-
}
103-
};
104+
return new CompareIpFunction(SqlKind.EQUALS);
104105
}
105106

106107
public static CompareIpFunction notEquals() {
107-
return new CompareIpFunction(ComparisonType.NOT_EQUALS) {
108-
@Override
109-
public SqlKind getKind() {
110-
return SqlKind.NOT_EQUALS;
111-
}
112-
};
108+
return new CompareIpFunction(SqlKind.NOT_EQUALS);
113109
}
114110

115111
@Override
@@ -123,10 +119,10 @@ public UDFOperandMetadata getOperandMetadata() {
123119
}
124120

125121
public static class CompareImplementor implements NotNullImplementor {
126-
private final ComparisonType comparisonType;
122+
private final SqlKind compareType;
127123

128-
public CompareImplementor(ComparisonType comparisonType) {
129-
this.comparisonType = comparisonType;
124+
public CompareImplementor(SqlKind compareType) {
125+
this.compareType = compareType;
130126
}
131127

132128
@Override
@@ -139,19 +135,20 @@ public Expression implement(
139135
translatedOperands.get(0),
140136
translatedOperands.get(1));
141137

142-
return evalCompareResult(compareResult, comparisonType);
138+
return evalCompareResult(compareResult, compareType);
143139
}
144140

145-
private static Expression evalCompareResult(
146-
Expression compareResult, ComparisonType comparisonType) {
141+
private static Expression evalCompareResult(Expression compareResult, SqlKind compareType) {
147142
final ConstantExpression zero = Expressions.constant(0);
148-
return switch (comparisonType) {
143+
return switch (compareType) {
149144
case EQUALS -> Expressions.equal(compareResult, zero);
150145
case NOT_EQUALS -> Expressions.notEqual(compareResult, zero);
151-
case LESS -> Expressions.lessThan(compareResult, zero);
152-
case LESS_OR_EQUAL -> Expressions.lessThanOrEqual(compareResult, zero);
153-
case GREATER -> Expressions.greaterThan(compareResult, zero);
154-
case GREATER_OR_EQUAL -> Expressions.greaterThanOrEqual(compareResult, zero);
146+
case LESS_THAN -> Expressions.lessThan(compareResult, zero);
147+
case LESS_THAN_OR_EQUAL -> Expressions.lessThanOrEqual(compareResult, zero);
148+
case GREATER_THAN -> Expressions.greaterThan(compareResult, zero);
149+
case GREATER_THAN_OR_EQUAL -> Expressions.greaterThanOrEqual(compareResult, zero);
150+
default -> throw new UnsupportedOperationException(
151+
String.format(Locale.ROOT, "Unsupported compare type: %s", compareType));
155152
};
156153
}
157154

@@ -170,13 +167,4 @@ private static ExprIpValue toExprIpValue(Object obj) {
170167
throw new IllegalArgumentException("Invalid IP type: " + obj);
171168
}
172169
}
173-
174-
public enum ComparisonType {
175-
EQUALS,
176-
NOT_EQUALS,
177-
LESS,
178-
LESS_OR_EQUAL,
179-
GREATER,
180-
GREATER_OR_EQUAL
181-
}
182170
}

0 commit comments

Comments
 (0)