From e5ea51f7a8d2f4c097a18550cf4921e8961100d6 Mon Sep 17 00:00:00 2001
From: Nik Everett
+ * IPv4 addresses have traditionally parsed quads with leading zeros in three + * mutually exclusive ways: + *
+ *+ * These three ways of handling leading zeros are available with the optional + * {@code leading_zeros} named parameter. Set to {@code octal}, {@code decimal}, + * or {@code reject}. If not sent this defaults to {@code reject} which has + * been Elasticsearch's traditional way of handling leading zeros for years. + *
+ *+ * This doesn't extend from {@link AbstractConvertFunction} so that it can + * support a named parameter for the leading zeros behavior. Instead, it rewrites + * itself into either {@link ToIpLeadingZerosOctal}, {@link ToIpLeadingZerosDecimal}, + * or {@link ToIpLeadingZerosRejected} which are all {@link AbstractConvertFunction} + * subclasses. This keeps the conversion code happy while still allowing us to + * expose a single method to users. + *
+ */ +public class ToIp extends EsqlScalarFunction implements SurrogateExpression, OptionalArgument, ConvertFunction { + private static final String LEADING_ZEROS = "leading_zeros"; + public static final Map
@@ -545,6 +554,12 @@ public static ExpressionEvaluator.Factory evaluator(Expression e) {
if (e.foldable()) {
e = new Literal(e.source(), e.fold(FoldContext.small()), e.dataType());
}
+ if (e instanceof SurrogateExpression s) {
+ Expression surrogate = s.surrogate();
+ if (surrogate != null) {
+ e = surrogate;
+ }
+ }
Layout.Builder builder = new Layout.Builder();
buildLayout(builder, e);
Expression.TypeResolution resolution = e.typeResolved();
@@ -705,6 +720,7 @@ private static BytesRef randomizeBytesRefOffset(BytesRef bytesRef) {
}
public void testSerializationOfSimple() {
+ assumeTrue("can't serialize function", canSerialize());
assertSerialization(buildFieldExpression(testCase), testCase.getConfiguration());
}
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractScalarFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractScalarFunctionTestCase.java
index 0cee8fe3f57cb..f056e0c61c8d1 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractScalarFunctionTestCase.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractScalarFunctionTestCase.java
@@ -25,6 +25,7 @@
import org.elasticsearch.xpack.esql.core.expression.FoldContext;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.util.NumericUtils;
+import org.elasticsearch.xpack.esql.expression.SurrogateExpression;
import org.elasticsearch.xpack.esql.optimizer.rules.logical.FoldNull;
import org.elasticsearch.xpack.esql.planner.PlannerUtils;
import org.hamcrest.Matcher;
@@ -366,6 +367,12 @@ public void testFold() {
return;
}
assertFalse("expected resolved", expression.typeResolved().unresolved());
+ if (expression instanceof SurrogateExpression s) {
+ Expression surrogate = s.surrogate();
+ if (surrogate != null) {
+ expression = surrogate;
+ }
+ }
Expression nullOptimized = new FoldNull().rule(expression, unboundLogicalOptimizerContext());
assertThat(nullOptimized.dataType(), equalTo(testCase.expectedType()));
assertTrue(nullOptimized.foldable());
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIPTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIPTests.java
deleted file mode 100644
index e666d7c6defe9..0000000000000
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToIPTests.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-package org.elasticsearch.xpack.esql.expression.function.scalar.convert;
-
-import com.carrotsearch.randomizedtesting.annotations.Name;
-import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
-
-import org.apache.lucene.util.BytesRef;
-import org.elasticsearch.common.network.NetworkAddress;
-import org.elasticsearch.test.ESTestCase;
-import org.elasticsearch.xpack.esql.core.expression.Expression;
-import org.elasticsearch.xpack.esql.core.tree.Source;
-import org.elasticsearch.xpack.esql.core.type.DataType;
-import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase;
-import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Supplier;
-
-import static java.util.Collections.emptyList;
-import static org.elasticsearch.xpack.esql.core.util.StringUtils.parseIP;
-
-public class ToIPTests extends AbstractScalarFunctionTestCase {
- public ToIPTests(@Name("TestCase") Supplier