This is an automated email from the ASF dual-hosted git repository.
dianfu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git
The following commit(s) were added to refs/heads/master by this push:
new 3a4839487cc [FLINK-40196][table] Remove IS_NOT_NAN in favor of NOT
IS_NAN (#29639)
3a4839487cc is described below
commit 3a4839487cc629741e37dac5c22da1e7bd3059ae
Author: Matt Belle <[email protected]>
AuthorDate: Fri Oct 30 02:03:32 2026 -0400
[FLINK-40196][table] Remove IS_NOT_NAN in favor of NOT IS_NAN (#29639)
IS_NOT_NAN only flips the result of IS_NAN. Unlike IS NOT NULL, it has
no grammar-level counterpart in SQL, and other engines (Spark, BigQuery,
Trino) only offer IS_NAN and rely on negation. Drop the dedicated
function from the Java and Python Table APIs, the runtime, and the docs,
and express it as not_(is_nan(...)) instead.
Generated-by: Claude Code 2.1.309
---
docs/data/sql_functions.yml | 3 --
docs/data/sql_functions_zh.yml | 3 --
.../docs/reference/pyflink.table/expressions.rst | 2 -
flink-python/pyflink/dataframe/dataframe.py | 6 +--
.../pyflink/dataframe/tests/test_dataframe.py | 11 ++--
flink-python/pyflink/table/expression.py | 11 ----
flink-python/pyflink/table/expressions.py | 13 +----
.../org/apache/flink/table/api/Expressions.java | 10 ----
.../flink/table/api/internal/BaseExpressions.java | 6 ---
.../functions/BuiltInFunctionDefinitions.java | 11 ----
.../runtime/functions/scalar/IsNotNanFunction.java | 63 ----------------------
11 files changed, 8 insertions(+), 131 deletions(-)
diff --git a/docs/data/sql_functions.yml b/docs/data/sql_functions.yml
index fadf6f734b4..4369dfab0f3 100644
--- a/docs/data/sql_functions.yml
+++ b/docs/data/sql_functions.yml
@@ -43,9 +43,6 @@ comparison:
- sql: IS_NAN(value)
table: value.isNan
description: Returns TRUE if value is NaN; returns FALSE if value is a
non-NaN numeric value; returns NULL if value is NULL.
- - sql: IS_NOT_NAN(value)
- table: value.isNotNan
- description: Returns TRUE if value is a non-NaN numeric value; returns
FALSE if value is NaN; returns NULL if value is NULL.
- sql: value1 IS DISTINCT FROM value2
description: Returns TRUE if two values are different. NULL values are
treated as identical here. E.g., 1 IS DISTINCT FROM NULL returns TRUE; NULL IS
DISTINCT FROM NULL returns FALSE.
- sql: value1 IS NOT DISTINCT FROM value2
diff --git a/docs/data/sql_functions_zh.yml b/docs/data/sql_functions_zh.yml
index c9b379fcbe2..6ff92d7f48f 100644
--- a/docs/data/sql_functions_zh.yml
+++ b/docs/data/sql_functions_zh.yml
@@ -43,9 +43,6 @@ comparison:
- sql: IS_NAN(value)
table: value.isNan
description: 如果值为 `NaN` 返回 `TRUE`;如果值是非 `NaN` 的数值返回 `FALSE`;如果值为 `NULL` 返回
`NULL`。
- - sql: IS_NOT_NAN(value)
- table: value.isNotNan
- description: 如果值是非 `NaN` 的数值返回 `TRUE`;如果值为 `NaN` 返回 `FALSE`;如果值为 `NULL` 返回
`NULL`。
- sql: value1 IS DISTINCT FROM value2
description: |
A 和 B 的数据类型和值不完全相同返回 `TRUE`。A 和 B 的数据类型和值都相同返回 `FALSE`。`NULL` 视为与任何其他值相同。
diff --git a/flink-python/docs/reference/pyflink.table/expressions.rst
b/flink-python/docs/reference/pyflink.table/expressions.rst
index 6c09c999e1c..47216929a4f 100644
--- a/flink-python/docs/reference/pyflink.table/expressions.rst
+++ b/flink-python/docs/reference/pyflink.table/expressions.rst
@@ -36,7 +36,6 @@ Expressions
or_
not_
is_nan
- is_not_nan
current_database
current_date
current_time
@@ -123,7 +122,6 @@ arithmetic functions
Expression.is_null
Expression.is_not_null
Expression.is_nan
- Expression.is_not_nan
Expression.is_true
Expression.is_false
Expression.is_not_true
diff --git a/flink-python/pyflink/dataframe/dataframe.py
b/flink-python/pyflink/dataframe/dataframe.py
index 7a90e1dfeb5..b4b1e9d85a3 100644
--- a/flink-python/pyflink/dataframe/dataframe.py
+++ b/flink-python/pyflink/dataframe/dataframe.py
@@ -67,8 +67,8 @@ from pyflink.table.expressions import (
col as table_col,
if_then_else,
is_nan,
- is_not_nan,
lit as table_lit,
+ not_,
or_,
)
from pyflink.table.table import Table
@@ -2390,9 +2390,9 @@ class DataFrame:
if not subset:
return self
- # Preserve NULL values: (is_not_nan(col) OR col IS NULL)
+ # Preserve NULL values: (NOT is_nan(col) OR col IS NULL)
conditions = [
- or_(is_not_nan(table_col(col_name)), table_col(col_name).is_null)
+ or_(not_(is_nan(table_col(col_name))), table_col(col_name).is_null)
for col_name in subset
]
condition = and_(*conditions) if len(conditions) > 1 else conditions[0]
diff --git a/flink-python/pyflink/dataframe/tests/test_dataframe.py
b/flink-python/pyflink/dataframe/tests/test_dataframe.py
index 35034b43c18..dd064573cfa 100644
--- a/flink-python/pyflink/dataframe/tests/test_dataframe.py
+++ b/flink-python/pyflink/dataframe/tests/test_dataframe.py
@@ -45,7 +45,7 @@ from pyflink.table import (
TableSchema,
)
from pyflink.table.expression import Expression
-from pyflink.table.expressions import is_nan, is_not_nan
+from pyflink.table.expressions import is_nan
from pyflink.table.types import LocalZonedTimestampType, TimestampType
from pyflink.testing.test_case_utils import (
PyFlinkDataFrameUTTestCase,
@@ -4641,7 +4641,7 @@ class
DataFrameNullNanITTests(PyFlinkStreamDataFrameTestCase):
)
# "name" is a STRING column and should be silently ignored, not raise
- # or attempt to apply is_not_nan to it.
+ # or attempt to apply is_nan to it.
result = df.drop_nan(subset=["name", "score"]).collect()
self.assertEqual(len(result), 1)
self.assertEqual(result[0][0], 1)
@@ -4877,8 +4877,8 @@ class
DataFrameNullNanITTests(PyFlinkStreamDataFrameTestCase):
self.assertEqual(result[1][0], 2)
self.assertIsNone(result[1][1])
- def test_is_nan_and_is_not_nan_support_decimal_columns(self):
- """Regression test: IsNanFunction/IsNotNanFunction must dispatch on
DecimalData,
+ def test_is_nan_supports_decimal_columns(self):
+ """Regression test: IsNanFunction must dispatch on DecimalData,
not BigDecimal, since BuiltInScalarFunction receives internal
representations
and DECIMAL columns never matched an eval(BigDecimal) overload."""
df = pf.from_records(
@@ -4892,15 +4892,12 @@ class
DataFrameNullNanITTests(PyFlinkStreamDataFrameTestCase):
result = df.select(
"id",
is_nan_result=is_nan(pf.col("amount")),
- is_not_nan_result=is_not_nan(pf.col("amount")),
).collect()
self.assertEqual(result[0][0], 1)
self.assertEqual(result[0][1], False)
- self.assertEqual(result[0][2], True)
self.assertEqual(result[1][0], 2)
self.assertIsNone(result[1][1])
- self.assertIsNone(result[1][2])
if __name__ == "__main__":
diff --git a/flink-python/pyflink/table/expression.py
b/flink-python/pyflink/table/expression.py
index e497ecb5590..b79a63175a8 100644
--- a/flink-python/pyflink/table/expression.py
+++ b/flink-python/pyflink/table/expression.py
@@ -772,20 +772,9 @@ class Expression(Generic[T]):
def is_nan(self) -> 'Expression[bool]':
"""
Returns true if the given numeric expression is NaN (Not-a-Number).
-
- .. seealso:: :py:attr:`~Expression.is_not_nan`
"""
return _unary_op("isNan")(self)
- @property
- def is_not_nan(self) -> 'Expression[bool]':
- """
- Returns true if the given numeric expression is not NaN (Not-a-Number).
-
- .. seealso:: :py:attr:`~Expression.is_nan`
- """
- return _unary_op("isNotNan")(self)
-
@property
def distinct(self) -> 'Expression':
"""
diff --git a/flink-python/pyflink/table/expressions.py
b/flink-python/pyflink/table/expressions.py
index 560d1251596..0464f72267f 100644
--- a/flink-python/pyflink/table/expressions.py
+++ b/flink-python/pyflink/table/expressions.py
@@ -26,7 +26,7 @@ from pyflink.table.udf import UserDefinedFunctionWrapper
from pyflink.util.api_stability_decorators import PublicEvolving
from pyflink.util.java_utils import to_jarray, load_java_class
-__all__ = ['if_then_else', 'lit', 'col', 'range_', 'and_', 'or_', 'not_',
'is_nan', 'is_not_nan',
+__all__ = ['if_then_else', 'lit', 'col', 'range_', 'and_', 'or_', 'not_',
'is_nan',
'UNBOUNDED_ROW', 'UNBOUNDED_RANGE', 'CURRENT_ROW', 'CURRENT_RANGE',
'current_database',
'current_date', 'current_time', 'current_timestamp',
'current_watermark', 'local_time', 'local_timestamp',
@@ -197,17 +197,6 @@ def is_nan(expr) -> Expression[bool]:
return _unary_op("isNan", expr)
-@PublicEvolving()
-def is_not_nan(expr) -> Expression[bool]:
- """
- Returns true if the given numeric expression is not NaN (Not-a-Number).
-
- This method supports a three-valued logic by preserving NULL. This means
if the
- input expression is NULL, the result will also be NULL.
- """
- return _unary_op("isNotNan", expr)
-
-
"""
Offset constant to be used in the `preceding` clause of unbounded
:class:`~pyflink.table.window.Over`. Use this constant for a time interval.
diff --git
a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/Expressions.java
b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/Expressions.java
index 54bd18b8e71..cfb6d22adc9 100644
---
a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/Expressions.java
+++
b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/Expressions.java
@@ -233,16 +233,6 @@ public final class Expressions {
return apiCall(BuiltInFunctionDefinitions.IS_NAN, expression);
}
- /**
- * Returns true if the given numeric expression is not NaN (Not-a-Number).
- *
- * <p>This method supports a three-valued logic by preserving {@code
NULL}. This means if the
- * input expression is {@code NULL}, the result will also be {@code NULL}.
- */
- public static ApiExpression isNotNan(Object expression) {
- return apiCall(BuiltInFunctionDefinitions.IS_NOT_NAN, expression);
- }
-
/**
* Offset constant to be used in the {@code preceding} clause of unbounded
{@code Over} windows.
* Use this constant for a time interval. Unbounded over windows start
with the first row of a
diff --git
a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/internal/BaseExpressions.java
b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/internal/BaseExpressions.java
index a5d041aca8e..18f78d8f5d9 100644
---
a/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/internal/BaseExpressions.java
+++
b/flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/internal/BaseExpressions.java
@@ -135,7 +135,6 @@ import static
org.apache.flink.table.functions.BuiltInFunctionDefinitions.IS_FAL
import static
org.apache.flink.table.functions.BuiltInFunctionDefinitions.IS_JSON;
import static
org.apache.flink.table.functions.BuiltInFunctionDefinitions.IS_NAN;
import static
org.apache.flink.table.functions.BuiltInFunctionDefinitions.IS_NOT_FALSE;
-import static
org.apache.flink.table.functions.BuiltInFunctionDefinitions.IS_NOT_NAN;
import static
org.apache.flink.table.functions.BuiltInFunctionDefinitions.IS_NOT_NULL;
import static
org.apache.flink.table.functions.BuiltInFunctionDefinitions.IS_NOT_TRUE;
import static
org.apache.flink.table.functions.BuiltInFunctionDefinitions.IS_NULL;
@@ -547,11 +546,6 @@ public abstract class BaseExpressions<InType, OutType> {
return toApiSpecificExpression(unresolvedCall(IS_NAN, toExpr()));
}
- /** Returns true if the given numeric expression is not NaN
(Not-a-Number). Null if null. */
- public OutType isNotNan() {
- return toApiSpecificExpression(unresolvedCall(IS_NOT_NAN, toExpr()));
- }
-
/**
* Similar to a SQL distinct aggregation clause such as COUNT(DISTINCT a),
declares that an
* aggregation function is only applied on distinct input values.
diff --git
a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
index 31ab26c0401..882298546a0 100644
---
a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
+++
b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
@@ -2462,17 +2462,6 @@ public final class BuiltInFunctionDefinitions {
.runtimeClass("org.apache.flink.table.runtime.functions.scalar.IsNanFunction")
.build();
- public static final BuiltInFunctionDefinition IS_NOT_NAN =
- BuiltInFunctionDefinition.newBuilder()
- .name("isNotNan")
- .sqlName("IS_NOT_NAN")
- .kind(SCALAR)
-
.inputTypeStrategy(sequence(logical(LogicalTypeFamily.NUMERIC)))
-
.outputTypeStrategy(nullableIfArgs(explicit(DataTypes.BOOLEAN())))
- .runtimeClass(
-
"org.apache.flink.table.runtime.functions.scalar.IsNotNanFunction")
- .build();
-
// Catalog functions
//
--------------------------------------------------------------------------------------------
diff --git
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/IsNotNanFunction.java
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/IsNotNanFunction.java
deleted file mode 100644
index 5514c5cecf3..00000000000
---
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/IsNotNanFunction.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.flink.table.runtime.functions.scalar;
-
-import org.apache.flink.annotation.Internal;
-import org.apache.flink.table.data.DecimalData;
-import org.apache.flink.table.functions.BuiltInFunctionDefinitions;
-import org.apache.flink.table.functions.SpecializedFunction.SpecializedContext;
-
-import javax.annotation.Nullable;
-
-/** Implementation of {@link BuiltInFunctionDefinitions#IS_NOT_NAN}. */
-@Internal
-public final class IsNotNanFunction extends BuiltInScalarFunction {
-
- public IsNotNanFunction(SpecializedContext context) {
- super(BuiltInFunctionDefinitions.IS_NOT_NAN, context);
- }
-
- public @Nullable Boolean eval(final @Nullable Byte value) {
- return value == null ? null : true;
- }
-
- public @Nullable Boolean eval(final @Nullable Short value) {
- return value == null ? null : true;
- }
-
- public @Nullable Boolean eval(final @Nullable Integer value) {
- return value == null ? null : true;
- }
-
- public @Nullable Boolean eval(final @Nullable Long value) {
- return value == null ? null : true;
- }
-
- public @Nullable Boolean eval(final @Nullable Float value) {
- return value == null ? null : !Float.isNaN(value);
- }
-
- public @Nullable Boolean eval(final @Nullable Double value) {
- return value == null ? null : !Double.isNaN(value);
- }
-
- public @Nullable Boolean eval(final @Nullable DecimalData value) {
- return value == null ? null : true;
- }
-}