diff --git a/core/build.gradle b/core/build.gradle
index f36777030c..c596251342 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -57,6 +57,7 @@ dependencies {
api group: 'com.google.code.gson', name: 'gson', version: '2.8.9'
api group: 'com.tdunning', name: 't-digest', version: '3.3'
api project(':common')
+ implementation "com.github.seancfoley:ipaddress:5.4.2"
testImplementation('org.junit.jupiter:junit-jupiter:5.9.3')
testImplementation group: 'org.hamcrest', name: 'hamcrest-library', version: '2.1'
diff --git a/core/src/main/java/org/opensearch/sql/exception/QueryEngineException.java b/core/src/main/java/org/opensearch/sql/exception/QueryEngineException.java
index b3d13bef71..122d4963fa 100644
--- a/core/src/main/java/org/opensearch/sql/exception/QueryEngineException.java
+++ b/core/src/main/java/org/opensearch/sql/exception/QueryEngineException.java
@@ -11,4 +11,8 @@ public class QueryEngineException extends RuntimeException {
public QueryEngineException(String message) {
super(message);
}
+
+ public QueryEngineException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/core/src/main/java/org/opensearch/sql/exception/SemanticCheckException.java b/core/src/main/java/org/opensearch/sql/exception/SemanticCheckException.java
index 6e0c184af8..c43dfdffc8 100644
--- a/core/src/main/java/org/opensearch/sql/exception/SemanticCheckException.java
+++ b/core/src/main/java/org/opensearch/sql/exception/SemanticCheckException.java
@@ -7,7 +7,12 @@
/** Semantic Check Exception. */
public class SemanticCheckException extends QueryEngineException {
+
public SemanticCheckException(String message) {
super(message);
}
+
+ public SemanticCheckException(String message, Throwable cause) {
+ super(message, cause);
+ }
}
diff --git a/core/src/main/java/org/opensearch/sql/expression/DSL.java b/core/src/main/java/org/opensearch/sql/expression/DSL.java
index 9975afac7f..54bd35e70f 100644
--- a/core/src/main/java/org/opensearch/sql/expression/DSL.java
+++ b/core/src/main/java/org/opensearch/sql/expression/DSL.java
@@ -563,6 +563,10 @@ public static FunctionExpression regexp(Expression... expressions) {
return compile(FunctionProperties.None, BuiltinFunctionName.REGEXP, expressions);
}
+ public static FunctionExpression cidrmatch(Expression... expressions) {
+ return compile(FunctionProperties.None, BuiltinFunctionName.CIDRMATCH, expressions);
+ }
+
public static FunctionExpression concat(Expression... expressions) {
return compile(FunctionProperties.None, BuiltinFunctionName.CONCAT, expressions);
}
diff --git a/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregatorFunction.java b/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregatorFunctions.java
similarity index 99%
rename from core/src/main/java/org/opensearch/sql/expression/aggregation/AggregatorFunction.java
rename to core/src/main/java/org/opensearch/sql/expression/aggregation/AggregatorFunctions.java
index 631eb2e613..698fb20408 100644
--- a/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregatorFunction.java
+++ b/core/src/main/java/org/opensearch/sql/expression/aggregation/AggregatorFunctions.java
@@ -40,7 +40,7 @@
* count accepts values of all types.
*/
@UtilityClass
-public class AggregatorFunction {
+public class AggregatorFunctions {
/**
* Register Aggregation Function.
*
diff --git a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunctions.java
similarity index 86%
rename from core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java
rename to core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunctions.java
index a42a599ad8..411bd27993 100644
--- a/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunction.java
+++ b/core/src/main/java/org/opensearch/sql/expression/datetime/DateTimeFunctions.java
@@ -101,7 +101,7 @@
*/
@UtilityClass
@SuppressWarnings("unchecked")
-public class DateTimeFunction {
+public class DateTimeFunctions {
// The number of seconds per day
public static final long SECONDS_PER_DAY = 86400;
@@ -357,8 +357,8 @@ private DefaultFunctionResolver adddate() {
BuiltinFunctionName.ADDDATE.getName(),
(SerializableFunction>[])
(Stream.concat(
- get_date_add_date_sub_signatures(DateTimeFunction::exprAddDateInterval),
- get_adddate_subdate_signatures(DateTimeFunction::exprAddDateDays))
+ get_date_add_date_sub_signatures(DateTimeFunctions::exprAddDateInterval),
+ get_adddate_subdate_signatures(DateTimeFunctions::exprAddDateDays))
.toArray(SerializableFunction, ?>[]::new)));
}
@@ -375,41 +375,41 @@ private DefaultFunctionResolver addtime() {
return define(
BuiltinFunctionName.ADDTIME.getName(),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), TIME, TIME, TIME),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprAddTime), TIME, TIME, TIME),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime), TIME, TIME, DATE),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprAddTime), TIME, TIME, DATE),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprAddTime),
TIME,
TIME,
TIMESTAMP),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprAddTime),
TIMESTAMP,
DATE,
TIME),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprAddTime),
TIMESTAMP,
DATE,
DATE),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprAddTime),
TIMESTAMP,
DATE,
TIMESTAMP),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprAddTime),
TIMESTAMP,
TIMESTAMP,
TIME),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprAddTime),
TIMESTAMP,
TIMESTAMP,
DATE),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprAddTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprAddTime),
TIMESTAMP,
TIMESTAMP,
TIMESTAMP));
@@ -425,13 +425,13 @@ private DefaultFunctionResolver convert_tz() {
return define(
BuiltinFunctionName.CONVERT_TZ.getName(),
impl(
- nullMissingHandling(DateTimeFunction::exprConvertTZ),
+ nullMissingHandling(DateTimeFunctions::exprConvertTZ),
TIMESTAMP,
TIMESTAMP,
STRING,
STRING),
impl(
- nullMissingHandling(DateTimeFunction::exprConvertTZ),
+ nullMissingHandling(DateTimeFunctions::exprConvertTZ),
TIMESTAMP,
STRING,
STRING,
@@ -445,9 +445,9 @@ private DefaultFunctionResolver convert_tz() {
private DefaultFunctionResolver date() {
return define(
BuiltinFunctionName.DATE.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprDate), DATE, TIMESTAMP));
+ impl(nullMissingHandling(DateTimeFunctions::exprDate), DATE, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprDate), DATE, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprDate), DATE, TIMESTAMP));
}
/**
@@ -458,35 +458,35 @@ private DefaultFunctionResolver datediff() {
return define(
BuiltinFunctionName.DATEDIFF.getName(),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), LONG, DATE, DATE),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprDateDiff), LONG, DATE, DATE),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), LONG, DATE, TIME),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprDateDiff), LONG, DATE, TIME),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), LONG, TIME, DATE),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprDateDiff), LONG, TIME, DATE),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff), LONG, TIME, TIME),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprDateDiff), LONG, TIME, TIME),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprDateDiff),
LONG,
TIMESTAMP,
DATE),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprDateDiff),
LONG,
DATE,
TIMESTAMP),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprDateDiff),
LONG,
TIMESTAMP,
TIMESTAMP),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprDateDiff),
LONG,
TIMESTAMP,
TIME),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprDateDiff),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprDateDiff),
LONG,
TIME,
TIMESTAMP));
@@ -501,15 +501,15 @@ private DefaultFunctionResolver datediff() {
private FunctionResolver datetime() {
return define(
BuiltinFunctionName.DATETIME.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprDateTime), TIMESTAMP, STRING, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprDateTimeNoTimezone), TIMESTAMP, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprDateTime), TIMESTAMP, STRING, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprDateTimeNoTimezone), TIMESTAMP, STRING));
}
private DefaultFunctionResolver date_add() {
return define(
BuiltinFunctionName.DATE_ADD.getName(),
(SerializableFunction>[])
- get_date_add_date_sub_signatures(DateTimeFunction::exprAddDateInterval)
+ get_date_add_date_sub_signatures(DateTimeFunctions::exprAddDateInterval)
.toArray(SerializableFunction, ?>[]::new));
}
@@ -517,7 +517,7 @@ private DefaultFunctionResolver date_sub() {
return define(
BuiltinFunctionName.DATE_SUB.getName(),
(SerializableFunction>[])
- get_date_add_date_sub_signatures(DateTimeFunction::exprSubDateInterval)
+ get_date_add_date_sub_signatures(DateTimeFunctions::exprSubDateInterval)
.toArray(SerializableFunction, ?>[]::new));
}
@@ -525,9 +525,9 @@ private DefaultFunctionResolver date_sub() {
private DefaultFunctionResolver day() {
return define(
BuiltinFunctionName.DAY.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfMonth), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfMonth), INTEGER, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfMonth), INTEGER, STRING));
}
/**
@@ -537,9 +537,9 @@ private DefaultFunctionResolver day() {
private DefaultFunctionResolver dayName() {
return define(
BuiltinFunctionName.DAYNAME.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprDayName), STRING, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprDayName), STRING, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprDayName), STRING, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprDayName), STRING, STRING));
}
/** DAYOFMONTH(STRING/DATE/TIMESTAMP). return the day of the month (1-31). */
@@ -549,12 +549,12 @@ private DefaultFunctionResolver dayOfMonth(BuiltinFunctionName name) {
implWithProperties(
nullMissingHandlingWithProperties(
(functionProperties, arg) ->
- DateTimeFunction.dayOfMonthToday(functionProperties.getQueryStartClock())),
+ DateTimeFunctions.dayOfMonthToday(functionProperties.getQueryStartClock())),
INTEGER,
TIME),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfMonth), INTEGER, TIMESTAMP));
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfMonth), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfMonth), INTEGER, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfMonth), INTEGER, TIMESTAMP));
}
/**
@@ -567,12 +567,12 @@ private DefaultFunctionResolver dayOfWeek(FunctionName name) {
implWithProperties(
nullMissingHandlingWithProperties(
(functionProperties, arg) ->
- DateTimeFunction.dayOfWeekToday(functionProperties.getQueryStartClock())),
+ DateTimeFunctions.dayOfWeekToday(functionProperties.getQueryStartClock())),
INTEGER,
TIME),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfWeek), INTEGER, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfWeek), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfWeek), INTEGER, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfWeek), INTEGER, STRING));
}
/** DAYOFYEAR(STRING/DATE/TIMESTAMP). return the day of the year for date (1-366). */
@@ -582,111 +582,114 @@ private DefaultFunctionResolver dayOfYear(BuiltinFunctionName dayOfYear) {
implWithProperties(
nullMissingHandlingWithProperties(
(functionProperties, arg) ->
- DateTimeFunction.dayOfYearToday(functionProperties.getQueryStartClock())),
+ DateTimeFunctions.dayOfYearToday(functionProperties.getQueryStartClock())),
INTEGER,
TIME),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprDayOfYear), INTEGER, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfYear), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfYear), INTEGER, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprDayOfYear), INTEGER, STRING));
}
private DefaultFunctionResolver extract() {
return define(
BuiltinFunctionName.EXTRACT.getName(),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprExtractForTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprExtractForTime),
LONG,
STRING,
TIME),
- impl(nullMissingHandling(DateTimeFunction::exprExtract), LONG, STRING, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprExtract), LONG, STRING, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprExtract), LONG, STRING, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprExtract), LONG, STRING, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprExtract), LONG, STRING, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprExtract), LONG, STRING, STRING));
}
/** FROM_DAYS(LONG). return the date value given the day number N. */
private DefaultFunctionResolver from_days() {
return define(
BuiltinFunctionName.FROM_DAYS.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprFromDays), DATE, LONG));
+ impl(nullMissingHandling(DateTimeFunctions::exprFromDays), DATE, LONG));
}
private FunctionResolver from_unixtime() {
return define(
BuiltinFunctionName.FROM_UNIXTIME.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprFromUnixTime), TIMESTAMP, DOUBLE),
+ impl(nullMissingHandling(DateTimeFunctions::exprFromUnixTime), TIMESTAMP, DOUBLE),
impl(
- nullMissingHandling(DateTimeFunction::exprFromUnixTimeFormat), STRING, DOUBLE, STRING));
+ nullMissingHandling(DateTimeFunctions::exprFromUnixTimeFormat),
+ STRING,
+ DOUBLE,
+ STRING));
}
private DefaultFunctionResolver get_format() {
return define(
BuiltinFunctionName.GET_FORMAT.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprGetFormat), STRING, STRING, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprGetFormat), STRING, STRING, STRING));
}
/** HOUR(STRING/TIME/DATE/TIMESTAMP). return the hour value for time. */
private DefaultFunctionResolver hour(BuiltinFunctionName name) {
return define(
name.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, TIME),
- impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprHour), INTEGER, TIMESTAMP));
+ impl(nullMissingHandling(DateTimeFunctions::exprHour), INTEGER, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprHour), INTEGER, TIME),
+ impl(nullMissingHandling(DateTimeFunctions::exprHour), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprHour), INTEGER, TIMESTAMP));
}
private DefaultFunctionResolver last_day() {
return define(
BuiltinFunctionName.LAST_DAY.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprLastDay), DATE, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprLastDay), DATE, STRING),
implWithProperties(
nullMissingHandlingWithProperties(
(functionProperties, arg) ->
- DateTimeFunction.exprLastDayToday(functionProperties.getQueryStartClock())),
+ DateTimeFunctions.exprLastDayToday(functionProperties.getQueryStartClock())),
DATE,
TIME),
- impl(nullMissingHandling(DateTimeFunction::exprLastDay), DATE, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprLastDay), DATE, TIMESTAMP));
+ impl(nullMissingHandling(DateTimeFunctions::exprLastDay), DATE, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprLastDay), DATE, TIMESTAMP));
}
private FunctionResolver makedate() {
return define(
BuiltinFunctionName.MAKEDATE.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprMakeDate), DATE, DOUBLE, DOUBLE));
+ impl(nullMissingHandling(DateTimeFunctions::exprMakeDate), DATE, DOUBLE, DOUBLE));
}
private FunctionResolver maketime() {
return define(
BuiltinFunctionName.MAKETIME.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprMakeTime), TIME, DOUBLE, DOUBLE, DOUBLE));
+ impl(nullMissingHandling(DateTimeFunctions::exprMakeTime), TIME, DOUBLE, DOUBLE, DOUBLE));
}
/** MICROSECOND(STRING/TIME/TIMESTAMP). return the microsecond value for time. */
private DefaultFunctionResolver microsecond() {
return define(
BuiltinFunctionName.MICROSECOND.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, TIME),
- impl(nullMissingHandling(DateTimeFunction::exprMicrosecond), INTEGER, TIMESTAMP));
+ impl(nullMissingHandling(DateTimeFunctions::exprMicrosecond), INTEGER, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprMicrosecond), INTEGER, TIME),
+ impl(nullMissingHandling(DateTimeFunctions::exprMicrosecond), INTEGER, TIMESTAMP));
}
/** MINUTE(STRING/TIME/TIMESTAMP). return the minute value for time. */
private DefaultFunctionResolver minute(BuiltinFunctionName name) {
return define(
name.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, TIME),
- impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprMinute), INTEGER, TIMESTAMP));
+ impl(nullMissingHandling(DateTimeFunctions::exprMinute), INTEGER, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprMinute), INTEGER, TIME),
+ impl(nullMissingHandling(DateTimeFunctions::exprMinute), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprMinute), INTEGER, TIMESTAMP));
}
/** MINUTE(STRING/TIME/TIMESTAMP). return the minute value for time. */
private DefaultFunctionResolver minute_of_day() {
return define(
BuiltinFunctionName.MINUTE_OF_DAY.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprMinuteOfDay), INTEGER, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprMinuteOfDay), INTEGER, TIME),
- impl(nullMissingHandling(DateTimeFunction::exprMinuteOfDay), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprMinuteOfDay), INTEGER, TIMESTAMP));
+ impl(nullMissingHandling(DateTimeFunctions::exprMinuteOfDay), INTEGER, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprMinuteOfDay), INTEGER, TIME),
+ impl(nullMissingHandling(DateTimeFunctions::exprMinuteOfDay), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprMinuteOfDay), INTEGER, TIMESTAMP));
}
/** MONTH(STRING/DATE/TIMESTAMP). return the month for date (1-12). */
@@ -696,21 +699,21 @@ private DefaultFunctionResolver month(BuiltinFunctionName month) {
implWithProperties(
nullMissingHandlingWithProperties(
(functionProperties, arg) ->
- DateTimeFunction.monthOfYearToday(functionProperties.getQueryStartClock())),
+ DateTimeFunctions.monthOfYearToday(functionProperties.getQueryStartClock())),
INTEGER,
TIME),
- impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprMonth), INTEGER, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprMonth), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprMonth), INTEGER, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprMonth), INTEGER, STRING));
}
/** MONTHNAME(STRING/DATE/TIMESTAMP). return the full name of the month for date. */
private DefaultFunctionResolver monthName() {
return define(
BuiltinFunctionName.MONTHNAME.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprMonthName), STRING, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprMonthName), STRING, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprMonthName), STRING, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprMonthName), STRING, STRING));
}
/**
@@ -720,7 +723,7 @@ private DefaultFunctionResolver monthName() {
private DefaultFunctionResolver period_add() {
return define(
BuiltinFunctionName.PERIOD_ADD.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprPeriodAdd), INTEGER, INTEGER, INTEGER));
+ impl(nullMissingHandling(DateTimeFunctions::exprPeriodAdd), INTEGER, INTEGER, INTEGER));
}
/**
@@ -731,35 +734,35 @@ private DefaultFunctionResolver period_add() {
private DefaultFunctionResolver period_diff() {
return define(
BuiltinFunctionName.PERIOD_DIFF.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprPeriodDiff), INTEGER, INTEGER, INTEGER));
+ impl(nullMissingHandling(DateTimeFunctions::exprPeriodDiff), INTEGER, INTEGER, INTEGER));
}
/** QUARTER(STRING/DATE/TIMESTAMP). return the month for date (1-4). */
private DefaultFunctionResolver quarter() {
return define(
BuiltinFunctionName.QUARTER.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprQuarter), INTEGER, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprQuarter), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprQuarter), INTEGER, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprQuarter), INTEGER, STRING));
}
private DefaultFunctionResolver sec_to_time() {
return define(
BuiltinFunctionName.SEC_TO_TIME.getName(),
- impl((nullMissingHandling(DateTimeFunction::exprSecToTime)), TIME, INTEGER),
- impl((nullMissingHandling(DateTimeFunction::exprSecToTime)), TIME, LONG),
- impl((nullMissingHandling(DateTimeFunction::exprSecToTimeWithNanos)), TIME, DOUBLE),
- impl((nullMissingHandling(DateTimeFunction::exprSecToTimeWithNanos)), TIME, FLOAT));
+ impl((nullMissingHandling(DateTimeFunctions::exprSecToTime)), TIME, INTEGER),
+ impl((nullMissingHandling(DateTimeFunctions::exprSecToTime)), TIME, LONG),
+ impl((nullMissingHandling(DateTimeFunctions::exprSecToTimeWithNanos)), TIME, DOUBLE),
+ impl((nullMissingHandling(DateTimeFunctions::exprSecToTimeWithNanos)), TIME, FLOAT));
}
/** SECOND(STRING/TIME/TIMESTAMP). return the second value for time. */
private DefaultFunctionResolver second(BuiltinFunctionName name) {
return define(
name.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, TIME),
- impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprSecond), INTEGER, TIMESTAMP));
+ impl(nullMissingHandling(DateTimeFunctions::exprSecond), INTEGER, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprSecond), INTEGER, TIME),
+ impl(nullMissingHandling(DateTimeFunctions::exprSecond), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprSecond), INTEGER, TIMESTAMP));
}
private DefaultFunctionResolver subdate() {
@@ -767,8 +770,8 @@ private DefaultFunctionResolver subdate() {
BuiltinFunctionName.SUBDATE.getName(),
(SerializableFunction>[])
(Stream.concat(
- get_date_add_date_sub_signatures(DateTimeFunction::exprSubDateInterval),
- get_adddate_subdate_signatures(DateTimeFunction::exprSubDateDays))
+ get_date_add_date_sub_signatures(DateTimeFunctions::exprSubDateInterval),
+ get_adddate_subdate_signatures(DateTimeFunctions::exprSubDateDays))
.toArray(SerializableFunction, ?>[]::new)));
}
@@ -785,41 +788,41 @@ private DefaultFunctionResolver subtime() {
return define(
BuiltinFunctionName.SUBTIME.getName(),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), TIME, TIME, TIME),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprSubTime), TIME, TIME, TIME),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime), TIME, TIME, DATE),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprSubTime), TIME, TIME, DATE),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprSubTime),
TIME,
TIME,
TIMESTAMP),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprSubTime),
TIMESTAMP,
TIMESTAMP,
TIME),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprSubTime),
TIMESTAMP,
TIMESTAMP,
DATE),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprSubTime),
TIMESTAMP,
DATE,
TIME),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprSubTime),
TIMESTAMP,
DATE,
DATE),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprSubTime),
TIMESTAMP,
DATE,
TIMESTAMP),
implWithProperties(
- nullMissingHandlingWithProperties(DateTimeFunction::exprSubTime),
+ nullMissingHandlingWithProperties(DateTimeFunctions::exprSubTime),
TIMESTAMP,
TIMESTAMP,
TIMESTAMP));
@@ -835,7 +838,7 @@ private DefaultFunctionResolver str_to_date() {
implWithProperties(
nullMissingHandlingWithProperties(
(functionProperties, arg, format) ->
- DateTimeFunction.exprStrToDate(functionProperties, arg, format)),
+ DateTimeFunctions.exprStrToDate(functionProperties, arg, format)),
TIMESTAMP,
STRING,
STRING));
@@ -848,10 +851,10 @@ private DefaultFunctionResolver str_to_date() {
private DefaultFunctionResolver time() {
return define(
BuiltinFunctionName.TIME.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, TIME),
- impl(nullMissingHandling(DateTimeFunction::exprTime), TIME, TIMESTAMP));
+ impl(nullMissingHandling(DateTimeFunctions::exprTime), TIME, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprTime), TIME, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprTime), TIME, TIME),
+ impl(nullMissingHandling(DateTimeFunctions::exprTime), TIME, TIMESTAMP));
}
/**
@@ -867,16 +870,16 @@ private DefaultFunctionResolver time() {
private DefaultFunctionResolver timediff() {
return define(
BuiltinFunctionName.TIMEDIFF.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprTimeDiff), TIME, TIME, TIME));
+ impl(nullMissingHandling(DateTimeFunctions::exprTimeDiff), TIME, TIME, TIME));
}
/** TIME_TO_SEC(STRING/TIME/TIMESTAMP). return the time argument, converted to seconds. */
private DefaultFunctionResolver time_to_sec() {
return define(
BuiltinFunctionName.TIME_TO_SEC.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, TIME),
- impl(nullMissingHandling(DateTimeFunction::exprTimeToSec), LONG, TIMESTAMP));
+ impl(nullMissingHandling(DateTimeFunctions::exprTimeToSec), LONG, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprTimeToSec), LONG, TIME),
+ impl(nullMissingHandling(DateTimeFunctions::exprTimeToSec), LONG, TIMESTAMP));
}
/**
@@ -914,7 +917,7 @@ private DefaultFunctionResolver timestampadd() {
return define(
BuiltinFunctionName.TIMESTAMPADD.getName(),
impl(
- nullMissingHandling(DateTimeFunction::exprTimestampAdd),
+ nullMissingHandling(DateTimeFunctions::exprTimestampAdd),
TIMESTAMP,
STRING,
INTEGER,
@@ -943,7 +946,7 @@ private DefaultFunctionResolver timestampdiff() {
return define(
BuiltinFunctionName.TIMESTAMPDIFF.getName(),
impl(
- nullMissingHandling(DateTimeFunction::exprTimestampDiff),
+ nullMissingHandling(DateTimeFunctions::exprTimestampDiff),
TIMESTAMP,
STRING,
TIMESTAMP,
@@ -962,9 +965,9 @@ private DefaultFunctionResolver timestampdiff() {
private DefaultFunctionResolver to_days() {
return define(
BuiltinFunctionName.TO_DAYS.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, STRING),
- impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprToDays), LONG, DATE));
+ impl(nullMissingHandling(DateTimeFunctions::exprToDays), LONG, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprToDays), LONG, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprToDays), LONG, DATE));
}
/**
@@ -975,8 +978,8 @@ private DefaultFunctionResolver to_days() {
private DefaultFunctionResolver to_seconds() {
return define(
BuiltinFunctionName.TO_SECONDS.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprToSeconds), LONG, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprToSecondsForIntType), LONG, LONG));
+ impl(nullMissingHandling(DateTimeFunctions::exprToSeconds), LONG, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprToSecondsForIntType), LONG, LONG));
}
private FunctionResolver unix_timestamp() {
@@ -984,11 +987,11 @@ private FunctionResolver unix_timestamp() {
BuiltinFunctionName.UNIX_TIMESTAMP.getName(),
implWithProperties(
functionProperties ->
- DateTimeFunction.unixTimeStamp(functionProperties.getQueryStartClock()),
+ DateTimeFunctions.unixTimeStamp(functionProperties.getQueryStartClock()),
LONG),
- impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, DATE),
- impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::unixTimeStampOf), DOUBLE, DOUBLE));
+ impl(nullMissingHandling(DateTimeFunctions::unixTimeStampOf), DOUBLE, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::unixTimeStampOf), DOUBLE, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::unixTimeStampOf), DOUBLE, DOUBLE));
}
/** UTC_DATE(). return the current UTC Date in format yyyy-MM-dd */
@@ -1019,24 +1022,24 @@ private DefaultFunctionResolver week(BuiltinFunctionName week) {
implWithProperties(
nullMissingHandlingWithProperties(
(functionProperties, arg) ->
- DateTimeFunction.weekOfYearToday(
+ DateTimeFunctions.weekOfYearToday(
DEFAULT_WEEK_OF_YEAR_MODE, functionProperties.getQueryStartClock())),
INTEGER,
TIME),
- impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprWeekWithoutMode), INTEGER, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprWeekWithoutMode), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprWeekWithoutMode), INTEGER, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprWeekWithoutMode), INTEGER, STRING),
implWithProperties(
nullMissingHandlingWithProperties(
(functionProperties, time, modeArg) ->
- DateTimeFunction.weekOfYearToday(
+ DateTimeFunctions.weekOfYearToday(
modeArg, functionProperties.getQueryStartClock())),
INTEGER,
TIME,
INTEGER),
- impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, DATE, INTEGER),
- impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, TIMESTAMP, INTEGER),
- impl(nullMissingHandling(DateTimeFunction::exprWeek), INTEGER, STRING, INTEGER));
+ impl(nullMissingHandling(DateTimeFunctions::exprWeek), INTEGER, DATE, INTEGER),
+ impl(nullMissingHandling(DateTimeFunctions::exprWeek), INTEGER, TIMESTAMP, INTEGER),
+ impl(nullMissingHandling(DateTimeFunctions::exprWeek), INTEGER, STRING, INTEGER));
}
private DefaultFunctionResolver weekday() {
@@ -1050,18 +1053,18 @@ private DefaultFunctionResolver weekday() {
- 1)),
INTEGER,
TIME),
- impl(nullMissingHandling(DateTimeFunction::exprWeekday), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprWeekday), INTEGER, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprWeekday), INTEGER, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprWeekday), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprWeekday), INTEGER, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprWeekday), INTEGER, STRING));
}
/** YEAR(STRING/DATE/TIMESTAMP). return the year for date (1000-9999). */
private DefaultFunctionResolver year() {
return define(
BuiltinFunctionName.YEAR.getName(),
- impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprYear), INTEGER, STRING));
+ impl(nullMissingHandling(DateTimeFunctions::exprYear), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprYear), INTEGER, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprYear), INTEGER, STRING));
}
/** YEARWEEK(DATE[,mode]). return the week number for date. */
@@ -1075,9 +1078,9 @@ private DefaultFunctionResolver yearweek() {
DEFAULT_WEEK_OF_YEAR_MODE, functionProperties.getQueryStartClock())),
INTEGER,
TIME),
- impl(nullMissingHandling(DateTimeFunction::exprYearweekWithoutMode), INTEGER, DATE),
- impl(nullMissingHandling(DateTimeFunction::exprYearweekWithoutMode), INTEGER, TIMESTAMP),
- impl(nullMissingHandling(DateTimeFunction::exprYearweekWithoutMode), INTEGER, STRING),
+ impl(nullMissingHandling(DateTimeFunctions::exprYearweekWithoutMode), INTEGER, DATE),
+ impl(nullMissingHandling(DateTimeFunctions::exprYearweekWithoutMode), INTEGER, TIMESTAMP),
+ impl(nullMissingHandling(DateTimeFunctions::exprYearweekWithoutMode), INTEGER, STRING),
implWithProperties(
nullMissingHandlingWithProperties(
(functionProperties, time, modeArg) ->
@@ -1085,9 +1088,9 @@ private DefaultFunctionResolver yearweek() {
INTEGER,
TIME,
INTEGER),
- impl(nullMissingHandling(DateTimeFunction::exprYearweek), INTEGER, DATE, INTEGER),
- impl(nullMissingHandling(DateTimeFunction::exprYearweek), INTEGER, TIMESTAMP, INTEGER),
- impl(nullMissingHandling(DateTimeFunction::exprYearweek), INTEGER, STRING, INTEGER));
+ impl(nullMissingHandling(DateTimeFunctions::exprYearweek), INTEGER, DATE, INTEGER),
+ impl(nullMissingHandling(DateTimeFunctions::exprYearweek), INTEGER, TIMESTAMP, INTEGER),
+ impl(nullMissingHandling(DateTimeFunctions::exprYearweek), INTEGER, STRING, INTEGER));
}
/**
diff --git a/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java b/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java
index fd5ea14a2e..a67308c96a 100644
--- a/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java
+++ b/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java
@@ -132,6 +132,9 @@ public enum BuiltinFunctionName {
/** Text Functions. */
TOSTRING(FunctionName.of("tostring")),
+ /** IP Functions. */
+ CIDRMATCH(FunctionName.of("cidrmatch")),
+
/** Arithmetic Operators. */
ADD(FunctionName.of("+")),
ADDFUNCTION(FunctionName.of("add")),
diff --git a/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionRepository.java b/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionRepository.java
index 2e16d5f01f..79ea58b860 100644
--- a/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionRepository.java
+++ b/core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionRepository.java
@@ -24,16 +24,17 @@
import org.opensearch.sql.data.type.ExprType;
import org.opensearch.sql.exception.ExpressionEvaluationException;
import org.opensearch.sql.expression.Expression;
-import org.opensearch.sql.expression.aggregation.AggregatorFunction;
-import org.opensearch.sql.expression.datetime.DateTimeFunction;
+import org.opensearch.sql.expression.aggregation.AggregatorFunctions;
+import org.opensearch.sql.expression.datetime.DateTimeFunctions;
import org.opensearch.sql.expression.datetime.IntervalClause;
-import org.opensearch.sql.expression.operator.arthmetic.ArithmeticFunction;
-import org.opensearch.sql.expression.operator.arthmetic.MathematicalFunction;
-import org.opensearch.sql.expression.operator.convert.TypeCastOperator;
-import org.opensearch.sql.expression.operator.predicate.BinaryPredicateOperator;
-import org.opensearch.sql.expression.operator.predicate.UnaryPredicateOperator;
+import org.opensearch.sql.expression.ip.IPFunctions;
+import org.opensearch.sql.expression.operator.arthmetic.ArithmeticFunctions;
+import org.opensearch.sql.expression.operator.arthmetic.MathematicalFunctions;
+import org.opensearch.sql.expression.operator.convert.TypeCastOperators;
+import org.opensearch.sql.expression.operator.predicate.BinaryPredicateOperators;
+import org.opensearch.sql.expression.operator.predicate.UnaryPredicateOperators;
import org.opensearch.sql.expression.system.SystemFunctions;
-import org.opensearch.sql.expression.text.TextFunction;
+import org.opensearch.sql.expression.text.TextFunctions;
import org.opensearch.sql.expression.window.WindowFunctions;
import org.opensearch.sql.storage.StorageEngine;
@@ -69,18 +70,19 @@ public static synchronized BuiltinFunctionRepository getInstance() {
instance = new BuiltinFunctionRepository(new HashMap<>());
// Register all built-in functions
- ArithmeticFunction.register(instance);
- BinaryPredicateOperator.register(instance);
- MathematicalFunction.register(instance);
- UnaryPredicateOperator.register(instance);
- AggregatorFunction.register(instance);
- DateTimeFunction.register(instance);
+ ArithmeticFunctions.register(instance);
+ BinaryPredicateOperators.register(instance);
+ MathematicalFunctions.register(instance);
+ UnaryPredicateOperators.register(instance);
+ AggregatorFunctions.register(instance);
+ DateTimeFunctions.register(instance);
IntervalClause.register(instance);
WindowFunctions.register(instance);
- TextFunction.register(instance);
- TypeCastOperator.register(instance);
+ TextFunctions.register(instance);
+ TypeCastOperators.register(instance);
SystemFunctions.register(instance);
OpenSearchFunctions.register(instance);
+ IPFunctions.register(instance);
}
return instance;
}
diff --git a/core/src/main/java/org/opensearch/sql/expression/function/DefaultFunctionResolver.java b/core/src/main/java/org/opensearch/sql/expression/function/DefaultFunctionResolver.java
index 5d0f31594b..e1d0052723 100644
--- a/core/src/main/java/org/opensearch/sql/expression/function/DefaultFunctionResolver.java
+++ b/core/src/main/java/org/opensearch/sql/expression/function/DefaultFunctionResolver.java
@@ -61,7 +61,7 @@ public Pair resolve(FunctionSignature unreso
&& !FunctionSignature.isVarArgFunction(bestMatchEntry.getValue().getParamTypeList())) {
throw new ExpressionEvaluationException(
String.format(
- "%s function expected %s, but get %s",
+ "%s function expected %s, but got %s",
functionName,
formatFunctions(functionBundle.keySet()),
unresolvedSignature.formatTypes()));
diff --git a/core/src/main/java/org/opensearch/sql/expression/ip/IPFunctions.java b/core/src/main/java/org/opensearch/sql/expression/ip/IPFunctions.java
new file mode 100644
index 0000000000..b3e7fad211
--- /dev/null
+++ b/core/src/main/java/org/opensearch/sql/expression/ip/IPFunctions.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.opensearch.sql.expression.ip;
+
+import static org.opensearch.sql.data.type.ExprCoreType.BOOLEAN;
+import static org.opensearch.sql.data.type.ExprCoreType.STRING;
+import static org.opensearch.sql.expression.function.FunctionDSL.define;
+import static org.opensearch.sql.expression.function.FunctionDSL.impl;
+import static org.opensearch.sql.expression.function.FunctionDSL.nullMissingHandling;
+
+import inet.ipaddr.AddressStringException;
+import inet.ipaddr.IPAddressString;
+import inet.ipaddr.IPAddressStringParameters;
+import lombok.experimental.UtilityClass;
+import org.opensearch.sql.data.model.ExprValue;
+import org.opensearch.sql.data.model.ExprValueUtils;
+import org.opensearch.sql.exception.SemanticCheckException;
+import org.opensearch.sql.expression.function.BuiltinFunctionName;
+import org.opensearch.sql.expression.function.BuiltinFunctionRepository;
+import org.opensearch.sql.expression.function.DefaultFunctionResolver;
+
+/** Utility class that defines and registers IP functions. */
+@UtilityClass
+public class IPFunctions {
+
+ public void register(BuiltinFunctionRepository repository) {
+ repository.register(cidrmatch());
+ }
+
+ private DefaultFunctionResolver cidrmatch() {
+
+ // TODO #3145: Add support for IP address data type.
+ return define(
+ BuiltinFunctionName.CIDRMATCH.getName(),
+ impl(nullMissingHandling(IPFunctions::exprCidrMatch), BOOLEAN, STRING, STRING));
+ }
+
+ /**
+ * Returns whether the given IP address is within the specified inclusive CIDR IP address range.
+ * Supports both IPv4 and IPv6 addresses.
+ *
+ * @param addressExprValue IP address as a string (e.g. "198.51.100.14" or
+ * "2001:0db8::ff00:42:8329").
+ * @param rangeExprValue IP address range in CIDR notation as a string (e.g. "198.51.100.0/24" or
+ * "2001:0db8::/32")
+ * @return true if the address is in the range; otherwise false.
+ * @throws SemanticCheckException if the address or range is not valid, or if they do not use the
+ * same version (IPv4 or IPv6).
+ */
+ private ExprValue exprCidrMatch(ExprValue addressExprValue, ExprValue rangeExprValue) {
+
+ // TODO #3145: Update to support IP address data type.
+ String addressString = addressExprValue.stringValue();
+ String rangeString = rangeExprValue.stringValue();
+
+ final IPAddressStringParameters validationOptions =
+ new IPAddressStringParameters.Builder()
+ .allowEmpty(false)
+ .setEmptyAsLoopback(false)
+ .allow_inet_aton(false)
+ .allowSingleSegment(false)
+ .toParams();
+
+ // Get and validate IP address.
+ IPAddressString address =
+ new IPAddressString(addressExprValue.stringValue(), validationOptions);
+
+ try {
+ address.validate();
+ } catch (AddressStringException e) {
+ String msg =
+ String.format(
+ "IP address '%s' is not valid. Error details: %s", addressString, e.getMessage());
+ throw new SemanticCheckException(msg, e);
+ }
+
+ // Get and validate CIDR IP address range.
+ IPAddressString range = new IPAddressString(rangeExprValue.stringValue(), validationOptions);
+
+ try {
+ range.validate();
+ } catch (AddressStringException e) {
+ String msg =
+ String.format(
+ "CIDR IP address range '%s' is not valid. Error details: %s",
+ rangeString, e.getMessage());
+ throw new SemanticCheckException(msg, e);
+ }
+
+ // Address and range must use the same IP version (IPv4 or IPv6).
+ if (address.isIPv4() ^ range.isIPv4()) {
+ String msg =
+ String.format(
+ "IP address '%s' and CIDR IP address range '%s' are not compatible. Both must be"
+ + " either IPv4 or IPv6.",
+ addressString, rangeString);
+ throw new SemanticCheckException(msg);
+ }
+
+ return ExprValueUtils.booleanValue(range.contains(address));
+ }
+}
diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/ArithmeticFunction.java b/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/ArithmeticFunctions.java
similarity index 99%
rename from core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/ArithmeticFunction.java
rename to core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/ArithmeticFunctions.java
index 82b91e1d34..164de6d74c 100644
--- a/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/ArithmeticFunction.java
+++ b/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/ArithmeticFunctions.java
@@ -37,7 +37,7 @@
* module, Accepts two numbers and produces a number.
*/
@UtilityClass
-public class ArithmeticFunction {
+public class ArithmeticFunctions {
/**
* Register Arithmetic Function.
*
diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunction.java b/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunctions.java
similarity index 99%
rename from core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunction.java
rename to core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunctions.java
index 22f4b76573..102834f60d 100644
--- a/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunction.java
+++ b/core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunctions.java
@@ -46,7 +46,7 @@
import org.opensearch.sql.expression.function.SerializableFunction;
@UtilityClass
-public class MathematicalFunction {
+public class MathematicalFunctions {
/**
* Register Mathematical Functions.
*
diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java b/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperators.java
similarity index 99%
rename from core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java
rename to core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperators.java
index db4b29f3b9..55e223d94c 100644
--- a/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperator.java
+++ b/core/src/main/java/org/opensearch/sql/expression/operator/convert/TypeCastOperators.java
@@ -42,7 +42,8 @@
import org.opensearch.sql.expression.function.FunctionDSL;
@UtilityClass
-public class TypeCastOperator {
+public class TypeCastOperators {
+
/** Register Type Cast Operator. */
public static void register(BuiltinFunctionRepository repository) {
repository.register(castToString());
diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperator.java b/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperators.java
similarity index 98%
rename from core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperator.java
rename to core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperators.java
index bf6b3c22f5..96ff7785b7 100644
--- a/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperator.java
+++ b/core/src/main/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperators.java
@@ -36,7 +36,7 @@
* equalTo, Compare the left expression and right expression and produces a Boolean.
*/
@UtilityClass
-public class BinaryPredicateOperator {
+public class BinaryPredicateOperators {
/**
* Register Binary Predicate Function.
*
@@ -401,7 +401,7 @@ private static DefaultFunctionResolver notLike() {
BuiltinFunctionName.NOT_LIKE.getName(),
impl(
nullMissingHandling(
- (v1, v2) -> UnaryPredicateOperator.not(OperatorUtils.matches(v1, v2))),
+ (v1, v2) -> UnaryPredicateOperators.not(OperatorUtils.matches(v1, v2))),
BOOLEAN,
STRING,
STRING));
diff --git a/core/src/main/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperator.java b/core/src/main/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperators.java
similarity index 83%
rename from core/src/main/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperator.java
rename to core/src/main/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperators.java
index ad9d9ac934..07bb5b2299 100644
--- a/core/src/main/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperator.java
+++ b/core/src/main/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperators.java
@@ -30,7 +30,8 @@
* The definition of unary predicate function not, Accepts one Boolean value and produces a Boolean.
*/
@UtilityClass
-public class UnaryPredicateOperator {
+public class UnaryPredicateOperators {
+
/** Register Unary Predicate Function. */
public static void register(BuiltinFunctionRepository repository) {
repository.register(not());
@@ -45,7 +46,7 @@ public static void register(BuiltinFunctionRepository repository) {
private static DefaultFunctionResolver not() {
return FunctionDSL.define(
BuiltinFunctionName.NOT.getName(),
- FunctionDSL.impl(UnaryPredicateOperator::not, BOOLEAN, BOOLEAN));
+ FunctionDSL.impl(UnaryPredicateOperators::not, BOOLEAN, BOOLEAN));
}
/**
@@ -108,11 +109,10 @@ private static DefaultFunctionResolver ifFunction() {
org.apache.commons.lang3.tuple.Pair>>
functionsOne =
typeList.stream()
- .map(v -> impl((UnaryPredicateOperator::exprIf), v, BOOLEAN, v, v))
+ .map(v -> impl((UnaryPredicateOperators::exprIf), v, BOOLEAN, v, v))
.collect(Collectors.toList());
- DefaultFunctionResolver functionResolver = FunctionDSL.define(functionName, functionsOne);
- return functionResolver;
+ return FunctionDSL.define(functionName, functionsOne);
}
private static DefaultFunctionResolver ifNull() {
@@ -125,31 +125,28 @@ private static DefaultFunctionResolver ifNull() {
org.apache.commons.lang3.tuple.Pair>>
functionsOne =
typeList.stream()
- .map(v -> impl((UnaryPredicateOperator::exprIfNull), v, v, v))
+ .map(v -> impl((UnaryPredicateOperators::exprIfNull), v, v, v))
.collect(Collectors.toList());
- DefaultFunctionResolver functionResolver = FunctionDSL.define(functionName, functionsOne);
- return functionResolver;
+ return FunctionDSL.define(functionName, functionsOne);
}
private static DefaultFunctionResolver nullIf() {
FunctionName functionName = BuiltinFunctionName.NULLIF.getName();
List typeList = ExprCoreType.coreTypes();
- DefaultFunctionResolver functionResolver =
- FunctionDSL.define(
- functionName,
- typeList.stream()
- .map(v -> impl((UnaryPredicateOperator::exprNullIf), v, v, v))
- .collect(Collectors.toList()));
- return functionResolver;
+ return FunctionDSL.define(
+ functionName,
+ typeList.stream()
+ .map(v -> impl((UnaryPredicateOperators::exprNullIf), v, v, v))
+ .collect(Collectors.toList()));
}
/**
* v2 if v1 is null.
*
- * @param v1 varable 1
- * @param v2 varable 2
+ * @param v1 variable 1
+ * @param v2 variable 2
* @return v2 if v1 is null
*/
public static ExprValue exprIfNull(ExprValue v1, ExprValue v2) {
@@ -157,11 +154,11 @@ public static ExprValue exprIfNull(ExprValue v1, ExprValue v2) {
}
/**
- * return null if v1 equls to v2.
+ * return null if v1 equals to v2.
*
- * @param v1 varable 1
- * @param v2 varable 2
- * @return null if v1 equls to v2
+ * @param v1 variable 1
+ * @param v2 variable 2
+ * @return null if v1 equals to v2
*/
public static ExprValue exprNullIf(ExprValue v1, ExprValue v2) {
return v1.equals(v2) ? LITERAL_NULL : v1;
diff --git a/core/src/main/java/org/opensearch/sql/expression/text/TextFunction.java b/core/src/main/java/org/opensearch/sql/expression/text/TextFunctions.java
similarity index 95%
rename from core/src/main/java/org/opensearch/sql/expression/text/TextFunction.java
rename to core/src/main/java/org/opensearch/sql/expression/text/TextFunctions.java
index d670843551..8a5302070c 100644
--- a/core/src/main/java/org/opensearch/sql/expression/text/TextFunction.java
+++ b/core/src/main/java/org/opensearch/sql/expression/text/TextFunctions.java
@@ -38,7 +38,7 @@
* implementation should rely on ExprValue.
*/
@UtilityClass
-public class TextFunction {
+public class TextFunctions {
private static String EMPTY_STRING = "";
/**
@@ -76,9 +76,9 @@ public void register(BuiltinFunctionRepository repository) {
private DefaultFunctionResolver substringSubstr(FunctionName functionName) {
return define(
functionName,
- impl(nullMissingHandling(TextFunction::exprSubstrStart), STRING, STRING, INTEGER),
+ impl(nullMissingHandling(TextFunctions::exprSubstrStart), STRING, STRING, INTEGER),
impl(
- nullMissingHandling(TextFunction::exprSubstrStartLength),
+ nullMissingHandling(TextFunctions::exprSubstrStartLength),
STRING,
STRING,
INTEGER,
@@ -267,7 +267,7 @@ private DefaultFunctionResolver strcmp() {
private DefaultFunctionResolver right() {
return define(
BuiltinFunctionName.RIGHT.getName(),
- impl(nullMissingHandling(TextFunction::exprRight), STRING, STRING, INTEGER));
+ impl(nullMissingHandling(TextFunctions::exprRight), STRING, STRING, INTEGER));
}
/**
@@ -279,7 +279,7 @@ private DefaultFunctionResolver right() {
private DefaultFunctionResolver left() {
return define(
BuiltinFunctionName.LEFT.getName(),
- impl(nullMissingHandling(TextFunction::exprLeft), STRING, STRING, INTEGER));
+ impl(nullMissingHandling(TextFunctions::exprLeft), STRING, STRING, INTEGER));
}
/**
@@ -292,7 +292,7 @@ private DefaultFunctionResolver left() {
private DefaultFunctionResolver ascii() {
return define(
BuiltinFunctionName.ASCII.getName(),
- impl(nullMissingHandling(TextFunction::exprAscii), INTEGER, STRING));
+ impl(nullMissingHandling(TextFunctions::exprAscii), INTEGER, STRING));
}
/**
@@ -310,14 +310,15 @@ private DefaultFunctionResolver locate() {
BuiltinFunctionName.LOCATE.getName(),
impl(
nullMissingHandling(
- (SerializableBiFunction) TextFunction::exprLocate),
+ (SerializableBiFunction)
+ TextFunctions::exprLocate),
INTEGER,
STRING,
STRING),
impl(
nullMissingHandling(
(SerializableTriFunction)
- TextFunction::exprLocate),
+ TextFunctions::exprLocate),
INTEGER,
STRING,
STRING,
@@ -337,7 +338,8 @@ private DefaultFunctionResolver position() {
BuiltinFunctionName.POSITION.getName(),
impl(
nullMissingHandling(
- (SerializableBiFunction) TextFunction::exprLocate),
+ (SerializableBiFunction)
+ TextFunctions::exprLocate),
INTEGER,
STRING,
STRING));
@@ -353,7 +355,7 @@ private DefaultFunctionResolver position() {
private DefaultFunctionResolver replace() {
return define(
BuiltinFunctionName.REPLACE.getName(),
- impl(nullMissingHandling(TextFunction::exprReplace), STRING, STRING, STRING, STRING));
+ impl(nullMissingHandling(TextFunctions::exprReplace), STRING, STRING, STRING, STRING));
}
/**
@@ -365,7 +367,7 @@ private DefaultFunctionResolver replace() {
private DefaultFunctionResolver reverse() {
return define(
BuiltinFunctionName.REVERSE.getName(),
- impl(nullMissingHandling(TextFunction::exprReverse), STRING, STRING));
+ impl(nullMissingHandling(TextFunctions::exprReverse), STRING, STRING));
}
private static ExprValue exprSubstrStart(ExprValue exprValue, ExprValue start) {
diff --git a/core/src/main/java/org/opensearch/sql/planner/physical/FilterOperator.java b/core/src/main/java/org/opensearch/sql/planner/physical/FilterOperator.java
index ec61d53163..192ea5cb4f 100644
--- a/core/src/main/java/org/opensearch/sql/planner/physical/FilterOperator.java
+++ b/core/src/main/java/org/opensearch/sql/planner/physical/FilterOperator.java
@@ -13,13 +13,13 @@
import lombok.ToString;
import org.opensearch.sql.data.model.ExprValue;
import org.opensearch.sql.expression.Expression;
-import org.opensearch.sql.expression.operator.predicate.BinaryPredicateOperator;
+import org.opensearch.sql.expression.operator.predicate.BinaryPredicateOperators;
import org.opensearch.sql.storage.bindingtuple.BindingTuple;
/**
* The Filter operator represents WHERE clause and uses the conditions to evaluate the input {@link
* BindingTuple}. The Filter operator only returns the results that evaluated to true. The NULL and
- * MISSING are handled by the logic defined in {@link BinaryPredicateOperator}.
+ * MISSING are handled by the logic defined in {@link BinaryPredicateOperators}.
*/
@EqualsAndHashCode(callSuper = false)
@ToString
diff --git a/core/src/test/java/org/opensearch/sql/analysis/AnalyzerTest.java b/core/src/test/java/org/opensearch/sql/analysis/AnalyzerTest.java
index 8d935b11d2..2412bd9474 100644
--- a/core/src/test/java/org/opensearch/sql/analysis/AnalyzerTest.java
+++ b/core/src/test/java/org/opensearch/sql/analysis/AnalyzerTest.java
@@ -158,7 +158,7 @@ public void filter_relation_with_invalid_qualifiedName_ExpressionEvaluationExcep
"= function expected {[BYTE,BYTE],[SHORT,SHORT],[INTEGER,INTEGER],[LONG,LONG],"
+ "[FLOAT,FLOAT],[DOUBLE,DOUBLE],[STRING,STRING],[BOOLEAN,BOOLEAN],[DATE,DATE],"
+ "[TIME,TIME],[TIMESTAMP,TIMESTAMP],[INTERVAL,INTERVAL],"
- + "[STRUCT,STRUCT],[ARRAY,ARRAY]}, but get [STRING,INTEGER]",
+ + "[STRUCT,STRUCT],[ARRAY,ARRAY]}, but got [STRING,INTEGER]",
exception.getMessage());
}
diff --git a/core/src/test/java/org/opensearch/sql/expression/aggregation/PercentileApproxAggregatorTest.java b/core/src/test/java/org/opensearch/sql/expression/aggregation/PercentileApproxAggregatorTest.java
index ac617e7b32..33fc325204 100644
--- a/core/src/test/java/org/opensearch/sql/expression/aggregation/PercentileApproxAggregatorTest.java
+++ b/core/src/test/java/org/opensearch/sql/expression/aggregation/PercentileApproxAggregatorTest.java
@@ -13,11 +13,18 @@
package org.opensearch.sql.expression.aggregation;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
-import static org.opensearch.sql.data.model.ExprValueUtils.*;
-import static org.opensearch.sql.data.type.ExprCoreType.*;
+import static org.opensearch.sql.data.model.ExprValueUtils.integerValue;
+import static org.opensearch.sql.data.model.ExprValueUtils.longValue;
+import static org.opensearch.sql.data.type.ExprCoreType.DOUBLE;
+import static org.opensearch.sql.data.type.ExprCoreType.FLOAT;
+import static org.opensearch.sql.data.type.ExprCoreType.INTEGER;
+import static org.opensearch.sql.data.type.ExprCoreType.LONG;
+import static org.opensearch.sql.data.type.ExprCoreType.STRING;
import java.util.ArrayList;
import java.util.List;
@@ -195,7 +202,7 @@ public void test_percentile_with_invalid_size() {
"percentile_approx function expected"
+ " {[INTEGER,DOUBLE],[INTEGER,DOUBLE,DOUBLE],[LONG,DOUBLE],[LONG,DOUBLE,DOUBLE],"
+ "[FLOAT,DOUBLE],[FLOAT,DOUBLE,DOUBLE],[DOUBLE,DOUBLE],[DOUBLE,DOUBLE,DOUBLE]},"
- + " but get [DOUBLE,STRING]",
+ + " but got [DOUBLE,STRING]",
exception2.getMessage());
}
diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/DateAddAndAddDateTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/DateAddAndAddDateTest.java
index 519e97bdc6..b4ab3a8567 100644
--- a/core/src/test/java/org/opensearch/sql/expression/datetime/DateAddAndAddDateTest.java
+++ b/core/src/test/java/org/opensearch/sql/expression/datetime/DateAddAndAddDateTest.java
@@ -156,7 +156,7 @@ public void adddate_has_second_signature_but_not_date_add() {
() -> date_add(LocalDateTime.of(1961, 4, 12, 9, 7), 100500));
assertEquals(
"date_add function expected {[DATE,INTERVAL],[TIMESTAMP,INTERVAL],"
- + "[TIME,INTERVAL]}, but get [TIMESTAMP,INTEGER]",
+ + "[TIME,INTERVAL]}, but got [TIMESTAMP,INTEGER]",
exception.getMessage());
}
diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/DateSubAndSubDateTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/DateSubAndSubDateTest.java
index 123ecda0bd..897f49cfee 100644
--- a/core/src/test/java/org/opensearch/sql/expression/datetime/DateSubAndSubDateTest.java
+++ b/core/src/test/java/org/opensearch/sql/expression/datetime/DateSubAndSubDateTest.java
@@ -139,7 +139,7 @@ public void subdate_has_second_signature_but_not_date_sub() {
ExpressionEvaluationException.class,
() -> date_sub(LocalDateTime.of(1961, 4, 12, 9, 7), 100500));
assertEquals(
- "date_sub function expected {[DATE,INTERVAL],[TIMESTAMP,INTERVAL],[TIME,INTERVAL]}, but get"
+ "date_sub function expected {[DATE,INTERVAL],[TIMESTAMP,INTERVAL],[TIME,INTERVAL]}, but got"
+ " [TIMESTAMP,INTEGER]",
exception.getMessage());
}
diff --git a/core/src/test/java/org/opensearch/sql/expression/datetime/ToSecondsTest.java b/core/src/test/java/org/opensearch/sql/expression/datetime/ToSecondsTest.java
index 910fe42a52..e983eb28f6 100644
--- a/core/src/test/java/org/opensearch/sql/expression/datetime/ToSecondsTest.java
+++ b/core/src/test/java/org/opensearch/sql/expression/datetime/ToSecondsTest.java
@@ -8,7 +8,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.opensearch.sql.data.type.ExprCoreType.LONG;
-import static org.opensearch.sql.expression.datetime.DateTimeFunction.SECONDS_PER_DAY;
+import static org.opensearch.sql.expression.datetime.DateTimeFunctions.SECONDS_PER_DAY;
import java.time.Duration;
import java.time.LocalDate;
diff --git a/core/src/test/java/org/opensearch/sql/expression/function/DefaultFunctionResolverTest.java b/core/src/test/java/org/opensearch/sql/expression/function/DefaultFunctionResolverTest.java
index ad9e8a6661..0c0439a764 100644
--- a/core/src/test/java/org/opensearch/sql/expression/function/DefaultFunctionResolverTest.java
+++ b/core/src/test/java/org/opensearch/sql/expression/function/DefaultFunctionResolverTest.java
@@ -72,7 +72,7 @@ void resolve_function_not_match() {
assertThrows(
ExpressionEvaluationException.class, () -> resolver.resolve(functionSignature));
assertEquals(
- "add function expected {[INTEGER,INTEGER]}, but get [BOOLEAN,BOOLEAN]",
+ "add function expected {[INTEGER,INTEGER]}, but got [BOOLEAN,BOOLEAN]",
exception.getMessage());
}
diff --git a/core/src/test/java/org/opensearch/sql/expression/ip/IPFunctionTest.java b/core/src/test/java/org/opensearch/sql/expression/ip/IPFunctionTest.java
new file mode 100644
index 0000000000..b50bf9fd1f
--- /dev/null
+++ b/core/src/test/java/org/opensearch/sql/expression/ip/IPFunctionTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.opensearch.sql.expression.ip;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.when;
+import static org.opensearch.sql.data.model.ExprValueUtils.LITERAL_FALSE;
+import static org.opensearch.sql.data.model.ExprValueUtils.LITERAL_TRUE;
+import static org.opensearch.sql.data.type.ExprCoreType.STRING;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.opensearch.sql.data.model.ExprValue;
+import org.opensearch.sql.data.model.ExprValueUtils;
+import org.opensearch.sql.exception.SemanticCheckException;
+import org.opensearch.sql.expression.DSL;
+import org.opensearch.sql.expression.Expression;
+import org.opensearch.sql.expression.FunctionExpression;
+import org.opensearch.sql.expression.env.Environment;
+
+@ExtendWith(MockitoExtension.class)
+public class IPFunctionTest {
+
+ // IP range and address constants for testing.
+ private static final ExprValue IPv4Range = ExprValueUtils.stringValue("198.51.100.0/24");
+ private static final ExprValue IPv6Range = ExprValueUtils.stringValue("2001:0db8::/32");
+
+ // TODO #3145: Add tests for IP address data type.
+ private static final ExprValue IPv4AddressBelow = ExprValueUtils.stringValue("198.51.99.1");
+ private static final ExprValue IPv4AddressWithin = ExprValueUtils.stringValue("198.51.100.1");
+ private static final ExprValue IPv4AddressAbove = ExprValueUtils.stringValue("198.51.101.2");
+
+ private static final ExprValue IPv6AddressBelow =
+ ExprValueUtils.stringValue("2001:0db7::ff00:42:8329");
+ private static final ExprValue IPv6AddressWithin =
+ ExprValueUtils.stringValue("2001:0db8::ff00:42:8329");
+ private static final ExprValue IPv6AddressAbove =
+ ExprValueUtils.stringValue("2001:0db9::ff00:42:8329");
+
+ // Mock value environment for testing.
+ @Mock private Environment env;
+
+ @Test
+ public void cidrmatch_invalid_address() {
+ SemanticCheckException exception =
+ assertThrows(
+ SemanticCheckException.class,
+ () -> execute(ExprValueUtils.stringValue("INVALID"), IPv4Range));
+ assertTrue(
+ exception.getMessage().matches("IP address 'INVALID' is not valid. Error details: .*"));
+ }
+
+ @Test
+ public void cidrmatch_invalid_range() {
+ SemanticCheckException exception =
+ assertThrows(
+ SemanticCheckException.class,
+ () -> execute(IPv4AddressWithin, ExprValueUtils.stringValue("INVALID")));
+ assertTrue(
+ exception
+ .getMessage()
+ .matches("CIDR IP address range 'INVALID' is not valid. Error details: .*"));
+ }
+
+ @Test
+ public void cidrmatch_different_versions() {
+ SemanticCheckException exception;
+
+ exception =
+ assertThrows(SemanticCheckException.class, () -> execute(IPv4AddressWithin, IPv6Range));
+ assertEquals(
+ "IP address '198.51.100.1' and CIDR IP address range '2001:0db8::/32' are not compatible."
+ + " Both must be either IPv4 or IPv6.",
+ exception.getMessage());
+
+ exception =
+ assertThrows(SemanticCheckException.class, () -> execute(IPv6AddressWithin, IPv4Range));
+ assertEquals(
+ "IP address '2001:0db8::ff00:42:8329' and CIDR IP address range '198.51.100.0/24' are not"
+ + " compatible. Both must be either IPv4 or IPv6.",
+ exception.getMessage());
+ }
+
+ @Test
+ public void cidrmatch_valid_ipv4() {
+ assertEquals(LITERAL_FALSE, execute(IPv4AddressBelow, IPv4Range));
+ assertEquals(LITERAL_TRUE, execute(IPv4AddressWithin, IPv4Range));
+ assertEquals(LITERAL_FALSE, execute(IPv4AddressAbove, IPv4Range));
+ }
+
+ @Test
+ public void cidrmatch_valid_ipv6() {
+ assertEquals(LITERAL_FALSE, execute(IPv6AddressBelow, IPv6Range));
+ assertEquals(LITERAL_TRUE, execute(IPv6AddressWithin, IPv6Range));
+ assertEquals(LITERAL_FALSE, execute(IPv6AddressAbove, IPv6Range));
+ }
+
+ /**
+ * Builds and evaluates a CIDR function expression with the given field and range expression
+ * values, and returns the resulting value.
+ */
+ private ExprValue execute(ExprValue field, ExprValue range) {
+
+ final String fieldName = "ip_address";
+ FunctionExpression exp = DSL.cidrmatch(DSL.ref(fieldName, STRING), DSL.literal(range));
+
+ // Mock the value environment to return the specified field
+ // expression as the value for the "ip_address" field.
+ when(DSL.ref(fieldName, STRING).valueOf(env)).thenReturn(field);
+
+ return exp.valueOf(env);
+ }
+}
diff --git a/core/src/test/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperatorTest.java b/core/src/test/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperatorTest.java
index 55dfbd35c2..19cbb4674e 100644
--- a/core/src/test/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperatorTest.java
+++ b/core/src/test/java/org/opensearch/sql/expression/operator/predicate/BinaryPredicateOperatorTest.java
@@ -584,7 +584,7 @@ void testRegexpString(StringPatternPair stringPatternPair) {
assertEquals(stringPatternPair.regExpTest(), expression.valueOf(valueEnv()).integerValue());
}
- /** Todo. remove this test cases after script serilization implemented. */
+ /** Todo. remove this test cases after script serialization implemented. */
@Test
public void serializationTest() throws Exception {
Expression expression = DSL.equal(DSL.literal("v1"), DSL.literal("v2"));
diff --git a/core/src/test/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperatorTest.java b/core/src/test/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperatorTest.java
index f7a1a7008a..7de4f456c9 100644
--- a/core/src/test/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperatorTest.java
+++ b/core/src/test/java/org/opensearch/sql/expression/operator/predicate/UnaryPredicateOperatorTest.java
@@ -221,12 +221,12 @@ public void test_if_predicate(Expression v1, Expression v2, Expression v3, Expre
@ParameterizedTest
@MethodSource("exprIfNullArguments")
public void test_exprIfNull_predicate(ExprValue v1, ExprValue v2, ExprValue expected) {
- assertEquals(expected.value(), UnaryPredicateOperator.exprIfNull(v1, v2).value());
+ assertEquals(expected.value(), UnaryPredicateOperators.exprIfNull(v1, v2).value());
}
@ParameterizedTest
@MethodSource("exprNullIfArguments")
public void test_exprNullIf_predicate(ExprValue v1, ExprValue v2, ExprValue expected) {
- assertEquals(expected.value(), UnaryPredicateOperator.exprNullIf(v1, v2).value());
+ assertEquals(expected.value(), UnaryPredicateOperators.exprNullIf(v1, v2).value());
}
}
diff --git a/docs/category.json b/docs/category.json
index e90c674a2e..ca3d345e8b 100644
--- a/docs/category.json
+++ b/docs/category.json
@@ -28,12 +28,13 @@
"user/ppl/cmd/where.rst",
"user/ppl/general/identifiers.rst",
"user/ppl/general/datatypes.rst",
- "user/ppl/functions/math.rst",
- "user/ppl/functions/datetime.rst",
- "user/ppl/functions/string.rst",
"user/ppl/functions/condition.rst",
+ "user/ppl/functions/datetime.rst",
+ "user/ppl/functions/expressions.rst",
+ "user/ppl/functions/ip.rst",
+ "user/ppl/functions/math.rst",
"user/ppl/functions/relevance.rst",
- "user/ppl/functions/expressions.rst"
+ "user/ppl/functions/string.rst"
],
"sql_cli": [
"user/dql/expressions.rst",
diff --git a/docs/user/dql/metadata.rst b/docs/user/dql/metadata.rst
index fa233020a3..aba4eb0c75 100644
--- a/docs/user/dql/metadata.rst
+++ b/docs/user/dql/metadata.rst
@@ -35,7 +35,7 @@ Example 1: Show All Indices Information
SQL query::
os> SHOW TABLES LIKE '%'
- fetched rows / total rows = 9/9
+ fetched rows / total rows = 10/10
+----------------+-------------+-----------------+------------+---------+----------+------------+-----------+---------------------------+----------------+
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME | TABLE_TYPE | REMARKS | TYPE_CAT | TYPE_SCHEM | TYPE_NAME | SELF_REFERENCING_COL_NAME | REF_GENERATION |
|----------------+-------------+-----------------+------------+---------+----------+------------+-----------+---------------------------+----------------|
@@ -47,6 +47,7 @@ SQL query::
| docTestCluster | null | nested | BASE TABLE | null | null | null | null | null | null |
| docTestCluster | null | nyc_taxi | BASE TABLE | null | null | null | null | null | null |
| docTestCluster | null | people | BASE TABLE | null | null | null | null | null | null |
+ | docTestCluster | null | weblogs | BASE TABLE | null | null | null | null | null | null |
| docTestCluster | null | wildcard | BASE TABLE | null | null | null | null | null | null |
+----------------+-------------+-----------------+------------+---------+----------+------------+-----------+---------------------------+----------------+
diff --git a/docs/user/ppl/functions/condition.rst b/docs/user/ppl/functions/condition.rst
index 96c3e64e72..9ce130072e 100644
--- a/docs/user/ppl/functions/condition.rst
+++ b/docs/user/ppl/functions/condition.rst
@@ -101,7 +101,7 @@ NULLIF
Description
>>>>>>>>>>>
-Usage: nullif(field1, field2) return null if two parameters are same, otherwiser return field1.
+Usage: nullif(field1, field2) return null if two parameters are same, otherwise return field1.
Argument type: all the supported data type, (NOTE : if two parameters has different type, if two parameters has different type, you will fail semantic check)
@@ -152,7 +152,7 @@ IF
Description
>>>>>>>>>>>
-Usage: if(condition, expr1, expr2) return expr1 if condition is true, otherwiser return expr2.
+Usage: if(condition, expr1, expr2) return expr1 if condition is true, otherwise return expr2.
Argument type: all the supported data type, (NOTE : if expr1 and expr2 are different type, you will fail semantic check
diff --git a/docs/user/ppl/functions/ip.rst b/docs/user/ppl/functions/ip.rst
new file mode 100644
index 0000000000..3387974af5
--- /dev/null
+++ b/docs/user/ppl/functions/ip.rst
@@ -0,0 +1,38 @@
+====================
+IP Address Functions
+====================
+
+.. rubric:: Table of contents
+
+.. contents::
+ :local:
+ :depth: 1
+
+CIDRMATCH
+---------
+
+Description
+>>>>>>>>>>>
+
+Usage: `cidrmatch(ip, cidr)` checks if `ip` is within the specified `cidr` range.
+
+Argument type: STRING, STRING
+
+Return type: BOOLEAN
+
+Example:
+
+ os> source=weblogs | where cidrmatch(host, '199.120.110.0/24') | fields host
+ fetched rows / total rows = 1/1
+ +----------------+
+ | host |
+ |----------------|
+ | 199.120.110.21 |
+ +----------------+
+
+Note:
+ - `ip` can be an IPv4 or an IPv6 address
+ - `cidr` can be an IPv4 or an IPv6 block
+ - `ip` and `cidr` must be either both IPv4 or both IPv6
+ - `ip` and `cidr` must both be valid and non-empty/non-null
+
diff --git a/docs/user/ppl/index.rst b/docs/user/ppl/index.rst
index 1fa981b1b7..9525874c59 100644
--- a/docs/user/ppl/index.rst
+++ b/docs/user/ppl/index.rst
@@ -102,6 +102,8 @@ The query start with search command and then flowing a set of command delimited
- `System Functions `_
+ - `IP Address Functions `_
+
* **Optimization**
- `Optimization <../../user/optimization/optimization.rst>`_
diff --git a/doctest/test_data/weblogs.json b/doctest/test_data/weblogs.json
new file mode 100644
index 0000000000..4228e9c4d2
--- /dev/null
+++ b/doctest/test_data/weblogs.json
@@ -0,0 +1,6 @@
+{"index":{}}
+{"host": "199.72.81.55", "method": "GET", "url": "/history/apollo/", "response": "200", "bytes": "6245"}
+{"index":{}}
+{"host": "199.120.110.21", "method": "GET", "url": "/shuttle/missions/sts-73/mission-sts-73.html", "response": "200", "bytes": "4085"}
+{"index":{}}
+{"host": "205.212.115.106", "method": "GET", "url": "/shuttle/countdown/countdown.html", "response": "200", "bytes": "3985"}
diff --git a/doctest/test_docs.py b/doctest/test_docs.py
index 881078a9bd..1d46766c6d 100644
--- a/doctest/test_docs.py
+++ b/doctest/test_docs.py
@@ -29,7 +29,7 @@
WILDCARD = "wildcard"
NESTED = "nested"
DATASOURCES = ".ql-datasources"
-
+WEBLOGS = "weblogs"
class DocTestConnection(OpenSearchConnection):
@@ -122,6 +122,7 @@ def set_up_test_indices(test):
load_file("wildcard.json", index_name=WILDCARD)
load_file("nested_objects.json", index_name=NESTED)
load_file("datasources.json", index_name=DATASOURCES)
+ load_file("weblogs.json", index_name=WEBLOGS)
def load_file(filename, index_name):
@@ -150,7 +151,7 @@ def set_up(test):
def tear_down(test):
# drop leftover tables after each test
- test_data_client.indices.delete(index=[ACCOUNTS, EMPLOYEES, PEOPLE, ACCOUNT2, NYC_TAXI, BOOKS, APACHE, WILDCARD, NESTED], ignore_unavailable=True)
+ test_data_client.indices.delete(index=[ACCOUNTS, EMPLOYEES, PEOPLE, ACCOUNT2, NYC_TAXI, BOOKS, APACHE, WILDCARD, NESTED, WEBLOGS], ignore_unavailable=True)
docsuite = partial(doctest.DocFileSuite,
diff --git a/integ-test/src/test/java/org/opensearch/sql/legacy/JdbcTestIT.java b/integ-test/src/test/java/org/opensearch/sql/legacy/JdbcTestIT.java
index 74acad4f52..005119a9bc 100644
--- a/integ-test/src/test/java/org/opensearch/sql/legacy/JdbcTestIT.java
+++ b/integ-test/src/test/java/org/opensearch/sql/legacy/JdbcTestIT.java
@@ -155,7 +155,9 @@ public void dateFunctionNameCaseInsensitiveTest() {
public void ipTypeShouldPassJdbcFormatter() {
assertThat(
executeQuery(
- "SELECT host AS hostIP FROM " + TestsConstants.TEST_INDEX_WEBLOG + " ORDER BY hostIP",
+ "SELECT host_ip AS hostIP FROM "
+ + TestsConstants.TEST_INDEX_WEBLOG
+ + " ORDER BY hostIP",
"jdbc"),
containsString("\"type\": \"ip\""));
}
diff --git a/integ-test/src/test/java/org/opensearch/sql/ppl/IPFunctionIT.java b/integ-test/src/test/java/org/opensearch/sql/ppl/IPFunctionIT.java
new file mode 100644
index 0000000000..adb044d0d2
--- /dev/null
+++ b/integ-test/src/test/java/org/opensearch/sql/ppl/IPFunctionIT.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.opensearch.sql.ppl;
+
+import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_WEBLOG;
+import static org.opensearch.sql.util.MatcherUtils.rows;
+import static org.opensearch.sql.util.MatcherUtils.schema;
+import static org.opensearch.sql.util.MatcherUtils.verifyDataRows;
+import static org.opensearch.sql.util.MatcherUtils.verifySchema;
+
+import java.io.IOException;
+import org.json.JSONObject;
+import org.junit.jupiter.api.Test;
+
+public class IPFunctionIT extends PPLIntegTestCase {
+
+ @Override
+ public void init() throws IOException {
+ loadIndex(Index.WEBLOG);
+ }
+
+ @Test
+ public void test_cidrmatch() throws IOException {
+
+ // TODO #3145: Add tests for IP address data type.
+ JSONObject result;
+
+ // No matches
+ result =
+ executeQuery(
+ String.format(
+ "source=%s | where cidrmatch(host_string, '199.120.111.0/24') | fields host_string",
+ TEST_INDEX_WEBLOG));
+ verifySchema(result, schema("host_string", null, "string"));
+ verifyDataRows(result);
+
+ // One match
+ result =
+ executeQuery(
+ String.format(
+ "source=%s | where cidrmatch(host_string, '199.120.110.0/24') | fields host_string",
+ TEST_INDEX_WEBLOG));
+ verifySchema(result, schema("host_string", null, "string"));
+ verifyDataRows(result, rows("199.120.110.21"));
+
+ // Multiple matches
+ result =
+ executeQuery(
+ String.format(
+ "source=%s | where cidrmatch(host_string, '199.0.0.0/8') | fields host_string",
+ TEST_INDEX_WEBLOG));
+ verifySchema(result, schema("host_string", null, "string"));
+ verifyDataRows(result, rows("199.72.81.55"), rows("199.120.110.21"));
+ }
+}
diff --git a/integ-test/src/test/resources/indexDefinitions/weblogs_index_mapping.json b/integ-test/src/test/resources/indexDefinitions/weblogs_index_mapping.json
index 05b9784313..bff3e20bb9 100644
--- a/integ-test/src/test/resources/indexDefinitions/weblogs_index_mapping.json
+++ b/integ-test/src/test/resources/indexDefinitions/weblogs_index_mapping.json
@@ -1,9 +1,12 @@
{
"mappings": {
"properties": {
- "host": {
+ "host_ip": {
"type": "ip"
},
+ "host_string": {
+ "type": "keyword"
+ },
"method": {
"type": "text"
},
diff --git a/integ-test/src/test/resources/weblogs.json b/integ-test/src/test/resources/weblogs.json
index 4228e9c4d2..d2e9a968f8 100644
--- a/integ-test/src/test/resources/weblogs.json
+++ b/integ-test/src/test/resources/weblogs.json
@@ -1,6 +1,6 @@
{"index":{}}
-{"host": "199.72.81.55", "method": "GET", "url": "/history/apollo/", "response": "200", "bytes": "6245"}
+{"host_ip": "199.72.81.55", "host_string": "199.72.81.55", "method": "GET", "url": "/history/apollo/", "response": "200", "bytes": "6245"}
{"index":{}}
-{"host": "199.120.110.21", "method": "GET", "url": "/shuttle/missions/sts-73/mission-sts-73.html", "response": "200", "bytes": "4085"}
+{"host_ip": "199.120.110.21", "host_string": "199.120.110.21", "method": "GET", "url": "/shuttle/missions/sts-73/mission-sts-73.html", "response": "200", "bytes": "4085"}
{"index":{}}
-{"host": "205.212.115.106", "method": "GET", "url": "/shuttle/countdown/countdown.html", "response": "200", "bytes": "3985"}
+{"host_ip": "205.212.115.106", "host_string": "205.212.115.106", "method": "GET", "url": "/shuttle/countdown/countdown.html", "response": "200", "bytes": "3985"}
diff --git a/opensearch/src/main/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactory.java b/opensearch/src/main/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactory.java
index d9e21436b7..da51c34cec 100644
--- a/opensearch/src/main/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactory.java
+++ b/opensearch/src/main/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactory.java
@@ -87,9 +87,7 @@ public void extendTypeMapping(Map typeMapping) {
for (var field : typeMapping.keySet()) {
// Prevent overwriting, because aggregation engine may be not aware
// of all niceties of all types.
- if (!this.typeMapping.containsKey(field)) {
- this.typeMapping.put(field, typeMapping.get(field));
- }
+ this.typeMapping.putIfAbsent(field, typeMapping.get(field));
}
}
diff --git a/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprIpValueTest.java b/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprIpValueTest.java
index 38a4ad3199..5ee175f304 100644
--- a/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprIpValueTest.java
+++ b/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprIpValueTest.java
@@ -14,27 +14,28 @@
public class OpenSearchExprIpValueTest {
- private OpenSearchExprIpValue ipValue = new OpenSearchExprIpValue("192.168.0.1");
+ private final String ipString = "192.168.0.1";
+ private final OpenSearchExprIpValue ipValue = new OpenSearchExprIpValue(ipString);
@Test
- void value() {
- assertEquals("192.168.0.1", ipValue.value());
+ void testValue() {
+ assertEquals(ipString, ipValue.value());
}
@Test
- void type() {
+ void testType() {
assertEquals(OpenSearchIpType.of(), ipValue.type());
}
@Test
- void compare() {
- assertEquals(0, ipValue.compareTo(new OpenSearchExprIpValue("192.168.0.1")));
- assertEquals(ipValue, new OpenSearchExprIpValue("192.168.0.1"));
+ void testCompare() {
+ assertEquals(0, ipValue.compareTo(new OpenSearchExprIpValue(ipString)));
+ assertEquals(ipValue, new OpenSearchExprIpValue(ipString));
}
@Test
- void equal() {
- assertTrue(ipValue.equal(new OpenSearchExprIpValue("192.168.0.1")));
+ void testEqual() {
+ assertTrue(ipValue.equal(new OpenSearchExprIpValue(ipString)));
}
@Test
diff --git a/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactoryTest.java b/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactoryTest.java
index 5fd40ef6c4..d82926077e 100644
--- a/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactoryTest.java
+++ b/opensearch/src/test/java/org/opensearch/sql/opensearch/data/value/OpenSearchExprValueFactoryTest.java
@@ -62,6 +62,8 @@
class OpenSearchExprValueFactoryTest {
+ static final String fieldIp = "ipV";
+
private static final Map MAPPING =
new ImmutableMap.Builder()
.put("byteV", OpenSearchDataType.of(BYTE))
@@ -112,14 +114,13 @@ class OpenSearchExprValueFactoryTest {
"textKeywordV",
OpenSearchTextType.of(
Map.of("words", OpenSearchDataType.of(OpenSearchDataType.MappingType.Keyword))))
- .put("ipV", OpenSearchDataType.of(OpenSearchDataType.MappingType.Ip))
+ .put(fieldIp, OpenSearchDataType.of(OpenSearchDataType.MappingType.Ip))
.put("geoV", OpenSearchDataType.of(OpenSearchDataType.MappingType.GeoPoint))
.put("binaryV", OpenSearchDataType.of(OpenSearchDataType.MappingType.Binary))
.build();
-
+ private static final double TOLERANCE = 1E-5;
private final OpenSearchExprValueFactory exprValueFactory =
new OpenSearchExprValueFactory(MAPPING, true);
-
private final OpenSearchExprValueFactory exprValueFactoryNoArrays =
new OpenSearchExprValueFactory(MAPPING, false);
@@ -660,12 +661,13 @@ public void constructArrayOfGeoPointsReturnsAll() {
@Test
public void constructArrayOfIPsReturnsAll() {
+ final String ip1 = "192.168.0.1";
+ final String ip2 = "192.168.0.2";
+
assertEquals(
new ExprCollectionValue(
- List.of(
- new OpenSearchExprIpValue("192.168.0.1"),
- new OpenSearchExprIpValue("192.168.0.2"))),
- tupleValue("{\"ipV\":[\"192.168.0.1\",\"192.168.0.2\"]}").get("ipV"));
+ List.of(new OpenSearchExprIpValue(ip1), new OpenSearchExprIpValue(ip2))),
+ tupleValue(String.format("{\"%s\":[\"%s\",\"%s\"]}", fieldIp, ip1, ip2)).get(fieldIp));
}
@Test
@@ -741,13 +743,12 @@ public void constructStruct() {
@Test
public void constructIP() {
+ final String valueIp = "192.168.0.1";
assertEquals(
- new OpenSearchExprIpValue("192.168.0.1"),
- tupleValue("{\"ipV\":\"192.168.0.1\"}").get("ipV"));
+ new OpenSearchExprIpValue(valueIp),
+ tupleValue(String.format("{\"%s\":\"%s\"}", fieldIp, valueIp)).get(fieldIp));
}
- private static final double TOLERANCE = 1E-5;
-
@Test
public void constructGeoPoint() {
final double lat = 42.60355556;
diff --git a/ppl/src/main/antlr/OpenSearchPPLLexer.g4 b/ppl/src/main/antlr/OpenSearchPPLLexer.g4
index 9f707c13cd..21cee12675 100644
--- a/ppl/src/main/antlr/OpenSearchPPLLexer.g4
+++ b/ppl/src/main/antlr/OpenSearchPPLLexer.g4
@@ -322,6 +322,7 @@ CAST: 'CAST';
LIKE: 'LIKE';
ISNULL: 'ISNULL';
ISNOTNULL: 'ISNOTNULL';
+CIDRMATCH: 'CIDRMATCH';
// FLOWCONTROL FUNCTIONS
IFNULL: 'IFNULL';
diff --git a/ppl/src/main/antlr/OpenSearchPPLParser.g4 b/ppl/src/main/antlr/OpenSearchPPLParser.g4
index 4dc223b028..54ec23dcb9 100644
--- a/ppl/src/main/antlr/OpenSearchPPLParser.g4
+++ b/ppl/src/main/antlr/OpenSearchPPLParser.g4
@@ -629,6 +629,7 @@ conditionFunctionName
: LIKE
| ISNULL
| ISNOTNULL
+ | CIDRMATCH
;
// flow control function return non-boolean value
@@ -829,6 +830,7 @@ keywordsCanBeId
| textFunctionName
| mathematicalFunctionName
| positionFunctionName
+ | conditionFunctionName
// commands
| SEARCH
| DESCRIBE