55
66package org .opensearch .sql .expression .function .udf .ip ;
77
8+ import java .util .Collections ;
89import java .util .List ;
910import java .util .Locale ;
10- import java .util .function .Supplier ;
1111import org .apache .calcite .adapter .enumerable .NotNullImplementor ;
1212import org .apache .calcite .adapter .enumerable .NullPolicy ;
1313import org .apache .calcite .adapter .enumerable .RexToLixTranslator ;
1414import org .apache .calcite .linq4j .tree .ConstantExpression ;
1515import org .apache .calcite .linq4j .tree .Expression ;
1616import org .apache .calcite .linq4j .tree .Expressions ;
1717import org .apache .calcite .rex .RexCall ;
18+ import org .apache .calcite .sql .SqlIdentifier ;
1819import org .apache .calcite .sql .SqlKind ;
1920import org .apache .calcite .sql .SqlOperator ;
2021import org .apache .calcite .sql .SqlSyntax ;
22+ import org .apache .calcite .sql .parser .SqlParserPos ;
23+ import org .apache .calcite .sql .type .InferTypes ;
2124import org .apache .calcite .sql .type .ReturnTypes ;
2225import org .apache .calcite .sql .type .SqlReturnTypeInference ;
26+ import org .apache .calcite .sql .validate .SqlUserDefinedFunction ;
27+ import org .checkerframework .checker .nullness .qual .Nullable ;
2328import org .opensearch .sql .data .model .ExprIpValue ;
2429import org .opensearch .sql .data .type .ExprCoreType ;
2530import org .opensearch .sql .expression .function .ImplementorUDF ;
31+ import org .opensearch .sql .expression .function .PPLBuiltinOperators ;
2632import org .opensearch .sql .expression .function .UDFOperandMetadata ;
2733
2834/**
3844 */
3945public class CompareIpFunction extends ImplementorUDF {
4046 private final SqlKind kind ;
41- private Supplier <SqlOperator > reverse ;
4247
4348 private CompareIpFunction (SqlKind kind ) {
4449 super (new CompareImplementor (kind ), NullPolicy .ANY );
4550 this .kind = kind ;
46- // Will be set later
47- this .reverse = null ;
48- }
49-
50- @ Override
51- public SqlSyntax getSqlSyntax () {
52- return SqlSyntax .BINARY ;
53- }
54-
55- @ Override
56- public SqlKind getKind () {
57- return kind ;
58- }
59-
60- @ Override
61- public Supplier <SqlOperator > getReverse () {
62- return reverse ;
63- }
64-
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- */
82- public CompareIpFunction withReverse (Supplier <SqlOperator > supplier ) {
83- this .reverse = supplier ;
84- return this ;
8551 }
8652
8753 public static CompareIpFunction less () {
@@ -108,6 +74,44 @@ public static CompareIpFunction notEquals() {
10874 return new CompareIpFunction (SqlKind .NOT_EQUALS );
10975 }
11076
77+ @ Override
78+ public SqlUserDefinedFunction toUDF (String functionName , boolean isDeterministic ) {
79+ SqlIdentifier udfIdentifier =
80+ new SqlIdentifier (Collections .singletonList (functionName ), null , SqlParserPos .ZERO , null );
81+ return new SqlUserDefinedFunction (
82+ udfIdentifier ,
83+ kind ,
84+ getReturnTypeInference (),
85+ InferTypes .ANY_NULLABLE ,
86+ getOperandMetadata (),
87+ getFunction ()) {
88+ @ Override
89+ public boolean isDeterministic () {
90+ return isDeterministic ;
91+ }
92+
93+ @ Override
94+ public @ Nullable SqlOperator reverse () {
95+ return switch (kind ) {
96+ case LESS_THAN -> PPLBuiltinOperators .GREATER_IP ;
97+ case GREATER_THAN -> PPLBuiltinOperators .LESS_IP ;
98+ case LESS_THAN_OR_EQUAL -> PPLBuiltinOperators .GTE_IP ;
99+ case GREATER_THAN_OR_EQUAL -> PPLBuiltinOperators .LTE_IP ;
100+ case EQUALS -> PPLBuiltinOperators .EQUALS_IP ;
101+ case NOT_EQUALS -> PPLBuiltinOperators .NOT_EQUALS_IP ;
102+ default -> throw new IllegalArgumentException (
103+ String .format (
104+ Locale .ROOT , "CompareIpFunction is not supposed to be of kind: %s" , kind ));
105+ };
106+ }
107+
108+ @ Override
109+ public SqlSyntax getSyntax () {
110+ return SqlSyntax .BINARY ;
111+ }
112+ };
113+ }
114+
111115 @ Override
112116 public SqlReturnTypeInference getReturnTypeInference () {
113117 return ReturnTypes .BOOLEAN_FORCE_NULLABLE ;
0 commit comments