66package org .opensearch .sql .expression .function .udf .ip ;
77
88import java .util .List ;
9+ import java .util .Locale ;
910import java .util .function .Supplier ;
1011import org .apache .calcite .adapter .enumerable .NotNullImplementor ;
1112import org .apache .calcite .adapter .enumerable .NullPolicy ;
3637 * </ul>
3738 */
3839public 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