This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 57391671424 [feature](window_function) support to secondary argument 
to ignore null values in first_value/last_value (#27623)
57391671424 is described below

commit 57391671424c4cf3ad9866ae1c7079eaef78f055
Author: Jerry Hu <[email protected]>
AuthorDate: Thu Nov 30 09:56:43 2023 +0800

    [feature](window_function) support to secondary argument to ignore null 
values in first_value/last_value (#27623)
---
 .../aggregate_function_window.cpp                  |  27 +++-
 .../aggregate_function_window.h                    |  37 ++++-
 .../java/org/apache/doris/catalog/FunctionSet.java |  20 ++-
 .../rules/analysis/WindowFunctionChecker.java      |   2 +-
 .../functions/window/FirstOrLastValue.java         |  23 ++-
 .../expressions/functions/window/FirstValue.java   |  14 +-
 .../expressions/functions/window/LastValue.java    |  12 +-
 ...ays_nullable_window_function_legacy_planner.out |  97 +++++++++++++
 .../correctness_p0/test_first_value_window.out     |  21 +++
 ... => test_first_value_window_legacy_planner.out} |  21 +++
 .../data/correctness_p0/test_last_value_window.out |  15 ++
 ...t => test_last_value_window_legacy_planner.out} |  15 ++
 .../test_always_nullable_window_function.groovy    |   2 +
 ...nullable_window_function_legacy_planner.groovy} |  24 +--
 .../correctness_p0/test_first_value_window.groovy  |  80 +++++++++-
 .../test_first_value_window_legacy_planner.groovy  | 161 +++++++++++++++++++++
 .../correctness_p0/test_last_value_window.groovy   |  42 +++++-
 ...> test_last_value_window_legacy_planner.groovy} |  47 +++++-
 18 files changed, 618 insertions(+), 42 deletions(-)

diff --git a/be/src/vec/aggregate_functions/aggregate_function_window.cpp 
b/be/src/vec/aggregate_functions/aggregate_function_window.cpp
index fdc8a0bf861..2b260e6baee 100644
--- a/be/src/vec/aggregate_functions/aggregate_function_window.cpp
+++ b/be/src/vec/aggregate_functions/aggregate_function_window.cpp
@@ -32,17 +32,32 @@
 namespace doris::vectorized {
 
 template <template <typename> class AggregateFunctionTemplate,
-          template <typename ColVecType, bool, bool> class Data, template 
<typename> class Impl,
-          bool result_is_nullable, bool arg_is_nullable>
+          template <typename ColVecType, bool, bool> class Data,
+          template <typename, bool> class Impl, bool result_is_nullable, bool 
arg_is_nullable>
 AggregateFunctionPtr create_function_lead_lag_first_last(const String& name,
                                                          const DataTypes& 
argument_types) {
     auto type = remove_nullable(argument_types[0]);
     WhichDataType which(*type);
 
-#define DISPATCH(TYPE, COLUMN_TYPE)                        \
-    if (which.idx == TypeIndex::TYPE)                      \
-        return std::make_shared<AggregateFunctionTemplate< \
-                Impl<Data<COLUMN_TYPE, result_is_nullable, 
arg_is_nullable>>>>(argument_types);
+    bool arg_ignore_null_value = false;
+    if (argument_types.size() == 2) {
+        DCHECK(name == "first_value" || name == "last_value") << "invalid 
function name: " << name;
+        arg_ignore_null_value = true;
+    }
+
+#define DISPATCH(TYPE, COLUMN_TYPE)                                            
            \
+    if (which.idx == TypeIndex::TYPE) {                                        
            \
+        if (arg_ignore_null_value) {                                           
            \
+            return std::make_shared<AggregateFunctionTemplate<                 
            \
+                    Impl<Data<COLUMN_TYPE, result_is_nullable, 
arg_is_nullable>, true>>>(  \
+                    argument_types);                                           
            \
+        } else {                                                               
            \
+            return std::make_shared<AggregateFunctionTemplate<                 
            \
+                    Impl<Data<COLUMN_TYPE, result_is_nullable, 
arg_is_nullable>, false>>>( \
+                    argument_types);                                           
            \
+        }                                                                      
            \
+    }
+
     TYPE_TO_COLUMN_TYPE(DISPATCH)
 #undef DISPATCH
 
diff --git a/be/src/vec/aggregate_functions/aggregate_function_window.h 
b/be/src/vec/aggregate_functions/aggregate_function_window.h
index a8fb89100db..808b48c4e36 100644
--- a/be/src/vec/aggregate_functions/aggregate_function_window.h
+++ b/be/src/vec/aggregate_functions/aggregate_function_window.h
@@ -309,7 +309,7 @@ private:
     bool _is_inited = false;
 };
 
-template <typename Data>
+template <typename Data, bool = false>
 struct WindowFunctionLeadImpl : Data {
     void add_range_single_place(int64_t partition_start, int64_t 
partition_end, int64_t frame_start,
                                 int64_t frame_end, const IColumn** columns) {
@@ -328,7 +328,7 @@ struct WindowFunctionLeadImpl : Data {
     static const char* name() { return "lead"; }
 };
 
-template <typename Data>
+template <typename Data, bool = false>
 struct WindowFunctionLagImpl : Data {
     void add_range_single_place(int64_t partition_start, int64_t 
partition_end, int64_t frame_start,
                                 int64_t frame_end, const IColumn** columns) {
@@ -350,7 +350,7 @@ struct WindowFunctionLagImpl : Data {
 // TODO: first_value && last_value in some corner case will be core,
 // if need to simply change it, should set them to always nullable insert into 
null value, and register in cpp maybe be change
 // But it's may be another better way to handle it
-template <typename Data>
+template <typename Data, bool arg_ignore_null = false>
 struct WindowFunctionFirstImpl : Data {
     void add_range_single_place(int64_t partition_start, int64_t 
partition_end, int64_t frame_start,
                                 int64_t frame_end, const IColumn** columns) {
@@ -363,13 +363,27 @@ struct WindowFunctionFirstImpl : Data {
             return;
         }
         frame_start = std::max<int64_t>(frame_start, partition_start);
+
+        if constexpr (arg_ignore_null) {
+            frame_end = std::min<int64_t>(frame_end, partition_end);
+
+            auto& second_arg = assert_cast<const 
ColumnVector<UInt8>&>(*columns[1]);
+            auto ignore_null_value = second_arg.get_data()[0];
+
+            if (ignore_null_value && columns[0]->is_nullable()) {
+                auto& arg_nullable = assert_cast<const 
ColumnNullable&>(*columns[0]);
+                while (frame_start < frame_end - 1 && 
arg_nullable.is_null_at(frame_start)) {
+                    frame_start++;
+                }
+            }
+        }
         this->set_value(columns, frame_start);
     }
 
     static const char* name() { return "first_value"; }
 };
 
-template <typename Data>
+template <typename Data, bool arg_ignore_null = false>
 struct WindowFunctionLastImpl : Data {
     void add_range_single_place(int64_t partition_start, int64_t 
partition_end, int64_t frame_start,
                                 int64_t frame_end, const IColumn** columns) {
@@ -380,6 +394,21 @@ struct WindowFunctionLastImpl : Data {
             return;
         }
         frame_end = std::min<int64_t>(frame_end, partition_end);
+
+        if constexpr (arg_ignore_null) {
+            frame_start = std::max<int64_t>(frame_start, partition_start);
+
+            auto& second_arg = assert_cast<const 
ColumnVector<UInt8>&>(*columns[1]);
+            auto ignore_null_value = second_arg.get_data()[0];
+
+            if (ignore_null_value && columns[0]->is_nullable()) {
+                auto& arg_nullable = assert_cast<const 
ColumnNullable&>(*columns[0]);
+                while (frame_start < (frame_end - 1) && 
arg_nullable.is_null_at(frame_end - 1)) {
+                    frame_end--;
+                }
+            }
+        }
+
         this->set_value(columns, frame_end - 1);
     }
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
index 70e974c40cd..e18370560c3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/FunctionSet.java
@@ -1426,6 +1426,22 @@ public class FunctionSet<T> {
                     null,
                     "",
                     "", true));
+
+            addBuiltin(AggregateFunction.createAnalyticBuiltin("first_value",
+                    Lists.newArrayList(new ArrayType(t), Type.BOOLEAN), new 
ArrayType(t), Type.ARRAY,
+                    "",
+                    "",
+                    null,
+                    "",
+                    "", true));
+
+            addBuiltin(AggregateFunction.createAnalyticBuiltin("last_value",
+                    Lists.newArrayList(new ArrayType(t), Type.BOOLEAN), new 
ArrayType(t), Type.ARRAY,
+                    "",
+                    "",
+                    null,
+                    "",
+                    "", true));
         }
 
         // Avg
@@ -1584,7 +1600,7 @@ public class FunctionSet<T> {
 
             //vec first_value
             addBuiltin(AggregateFunction.createAnalyticBuiltin(
-                    "first_value", Lists.newArrayList(t), t, t,
+                    "first_value", Lists.newArrayList(t, Type.BOOLEAN), t, t,
                     "",
                     "",
                     null,
@@ -1601,7 +1617,7 @@ public class FunctionSet<T> {
                     false, false));
             //vec last_value
             addBuiltin(AggregateFunction.createAnalyticBuiltin(
-                    "last_value", Lists.newArrayList(t), t, t,
+                    "last_value", Lists.newArrayList(t, Type.BOOLEAN), t, t,
                     "",
                     "",
                     "",
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/WindowFunctionChecker.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/WindowFunctionChecker.java
index 9c98fba59aa..9f5de748694 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/WindowFunctionChecker.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/WindowFunctionChecker.java
@@ -320,7 +320,7 @@ public class WindowFunctionChecker extends 
DefaultExpressionVisitor<Expression,
                     && wf.getLeftBoundary().isNot(FrameBoundType.PRECEDING)) {
                 windowExpression = windowExpression.withWindowFrame(
                         
wf.withFrameUnits(FrameUnitsType.ROWS).withRightBoundary(wf.getLeftBoundary()));
-                LastValue lastValue = new LastValue(firstValue.child());
+                LastValue lastValue = new LastValue(firstValue.children());
                 windowExpression = windowExpression.withFunction(lastValue);
                 return lastValue;
             }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/FirstOrLastValue.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/FirstOrLastValue.java
index 463fe41aab2..bb0a68eef6a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/FirstOrLastValue.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/FirstOrLastValue.java
@@ -21,30 +21,41 @@ import org.apache.doris.catalog.FunctionSignature;
 import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
 import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
-import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
+import org.apache.doris.nereids.types.BooleanType;
 import org.apache.doris.nereids.types.coercion.AnyDataType;
 
 import com.google.common.collect.ImmutableList;
 
 import java.util.List;
 
-/** parent class for first_value() and last_value() */
+/**
+ * parent class for first_value() and last_value()
+ */
 public abstract class FirstOrLastValue extends WindowFunction
-        implements UnaryExpression, AlwaysNullable, 
ExplicitlyCastableSignature {
+        implements AlwaysNullable, ExplicitlyCastableSignature {
 
     private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
-            
FunctionSignature.retArgType(0).args(AnyDataType.INSTANCE_WITHOUT_INDEX)
+            
FunctionSignature.retArgType(0).args(AnyDataType.INSTANCE_WITHOUT_INDEX),
+            
FunctionSignature.retArgType(0).args(AnyDataType.INSTANCE_WITHOUT_INDEX, 
BooleanType.INSTANCE)
     );
 
+    public FirstOrLastValue(String name, Expression child, Expression 
ignoreNullValue) {
+        super(name, child, ignoreNullValue);
+    }
+
     public FirstOrLastValue(String name, Expression child) {
         super(name, child);
     }
 
+    public FirstOrLastValue(String name, List<Expression> children) {
+        super(name, children);
+    }
+
     public FirstOrLastValue reverse() {
         if (this instanceof FirstValue) {
-            return new LastValue(child());
+            return new LastValue(children);
         } else {
-            return new FirstValue(child());
+            return new FirstValue(children);
         }
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/FirstValue.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/FirstValue.java
index 834f2f3a65a..5afacefc184 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/FirstValue.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/FirstValue.java
@@ -34,10 +34,18 @@ public class FirstValue extends FirstOrLastValue {
         super("first_value", child);
     }
 
+    public FirstValue(Expression child, Expression ignoreNullValue) {
+        super("first_value", child, ignoreNullValue);
+    }
+
+    public FirstValue(List<Expression> children) {
+        super("first_value", children);
+    }
+
     @Override
     public FirstValue withChildren(List<Expression> children) {
-        Preconditions.checkArgument(children.size() == 1);
-        return new FirstValue(children.get(0));
+        Preconditions.checkArgument(children.size() == 1 || children.size() == 
2);
+        return new FirstValue(children);
     }
 
     @Override
@@ -47,6 +55,6 @@ public class FirstValue extends FirstOrLastValue {
 
     @Override
     public DataType getDataType() {
-        return child().getDataType();
+        return child(0).getDataType();
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/LastValue.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/LastValue.java
index c2644b6ade3..a4759ba8d66 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/LastValue.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/window/LastValue.java
@@ -34,10 +34,18 @@ public class LastValue extends FirstOrLastValue {
         super("last_value", child);
     }
 
+    public LastValue(Expression child, Expression ignoreNullValue) {
+        super("last_value", child, ignoreNullValue);
+    }
+
+    public LastValue(List<Expression> children) {
+        super("last_value", children);
+    }
+
     @Override
     public LastValue withChildren(List<Expression> children) {
-        Preconditions.checkArgument(children.size() == 1);
-        return new LastValue(children.get(0));
+        Preconditions.checkArgument(children.size() == 1 || children.size() == 
2);
+        return new LastValue(children);
     }
 
     @Override
diff --git 
a/regression-test/data/correctness_p0/test_always_nullable_window_function_legacy_planner.out
 
b/regression-test/data/correctness_p0/test_always_nullable_window_function_legacy_planner.out
new file mode 100644
index 00000000000..b94f3ae38bb
--- /dev/null
+++ 
b/regression-test/data/correctness_p0/test_always_nullable_window_function_legacy_planner.out
@@ -0,0 +1,97 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !select_default --
+21     04-21-11        1       1       1       2       1.0     1       1       
\N      \N
+21     04-21-11        1       1       1       2       1.0     1       1       
\N      \N
+22     04-22-10-21     0       0       1       1       0.5     1       0       
\N      \N
+22     04-22-10-21     0       1       1       2       0.6666666666666666      
1       0       \N      \N
+22     04-22-10-21     1       0       0       1       0.3333333333333333      
1       0       \N      \N
+22     04-22-10-21     1       0       1       1       0.5     1       0       
\N      \N
+23     04-23-10        1       1       1       2       1.0     1       1       
\N      \N
+23     04-23-10        1       1       1       2       1.0     1       1       
\N      \N
+24     02-24-10-21     1       1       1       2       1.0     1       1       
\N      \N
+24     02-24-10-21     1       1       1       2       1.0     1       1       
\N      \N
+
+-- !select_empty_window --
+21     04-21-11        1       \N      \N      \N      \N      \N      \N      
\N      \N
+21     04-21-11        1       1       1       1       1.0     1       1       
\N      \N
+22     04-22-10-21     0       \N      \N      \N      \N      \N      \N      
\N      0
+22     04-22-10-21     0       1       1       1       1.0     1       1       
0       \N
+22     04-22-10-21     1       0       0       0       0.0     0       0       
\N      1
+22     04-22-10-21     1       0       0       0       0.0     0       0       
1       \N
+23     04-23-10        1       \N      \N      \N      \N      \N      \N      
\N      \N
+23     04-23-10        1       1       1       1       1.0     1       1       
\N      \N
+24     02-24-10-21     1       \N      \N      \N      \N      \N      \N      
\N      \N
+24     02-24-10-21     1       1       1       1       1.0     1       1       
\N      \N
+
+-- !select_default_nullable --
+21     04-21-11        1       1       1       2       1.0     1       1       
\N      \N
+21     04-21-11        1       1       1       2       1.0     1       1       
\N      \N
+22     04-22-10-21     0       0       1       1       0.5     1       0       
\N      \N
+22     04-22-10-21     0       1       1       2       0.6666666666666666      
1       0       \N      \N
+22     04-22-10-21     1       0       0       1       0.3333333333333333      
1       0       \N      \N
+22     04-22-10-21     1       0       1       1       0.5     1       0       
\N      \N
+23     04-23-10        1       1       1       2       1.0     1       1       
\N      \N
+23     04-23-10        1       1       1       2       1.0     1       1       
\N      \N
+24     02-24-10-21     1       1       1       2       1.0     1       1       
\N      \N
+24     02-24-10-21     1       1       1       2       1.0     1       1       
\N      \N
+
+-- !select_empty_window_nullable --
+21     04-21-11        1       \N      \N      \N      \N      \N      \N      
\N      \N
+21     04-21-11        1       1       1       1       1.0     1       1       
\N      \N
+22     04-22-10-21     0       \N      \N      \N      \N      \N      \N      
\N      0
+22     04-22-10-21     0       1       1       1       1.0     1       1       
0       \N
+22     04-22-10-21     1       0       0       0       0.0     0       0       
\N      1
+22     04-22-10-21     1       0       0       0       0.0     0       0       
1       \N
+23     04-23-10        1       \N      \N      \N      \N      \N      \N      
\N      \N
+23     04-23-10        1       1       1       1       1.0     1       1       
\N      \N
+24     02-24-10-21     1       \N      \N      \N      \N      \N      \N      
\N      \N
+24     02-24-10-21     1       1       1       1       1.0     1       1       
\N      \N
+
+-- !select_default_old_planner --
+21     04-21-11        1       1       1       2       1.0     1       1       
\N      1
+21     04-21-11        1       1       1       2       1.0     1       1       
1       \N
+22     04-22-10-21     0       0       1       1       0.5     1       0       
\N      1
+22     04-22-10-21     0       1       1       2       0.6666666666666666      
1       0       1       1
+22     04-22-10-21     1       0       0       1       0.3333333333333333      
1       0       0       0
+22     04-22-10-21     1       0       1       1       0.5     1       0       
0       \N
+23     04-23-10        1       1       1       2       1.0     1       1       
\N      1
+23     04-23-10        1       1       1       2       1.0     1       1       
1       \N
+24     02-24-10-21     1       1       1       2       1.0     1       1       
\N      1
+24     02-24-10-21     1       1       1       2       1.0     1       1       
1       \N
+
+-- !select_empty_window_old_planner --
+21     04-21-11        1       \N      \N      \N      \N      \N      \N      
\N      \N
+21     04-21-11        1       1       1       1       1.0     1       1       
\N      \N
+22     04-22-10-21     0       \N      \N      \N      \N      \N      \N      
\N      0
+22     04-22-10-21     0       1       1       1       1.0     1       1       
0       \N
+22     04-22-10-21     1       0       0       0       0.0     0       0       
\N      1
+22     04-22-10-21     1       0       0       0       0.0     0       0       
1       \N
+23     04-23-10        1       \N      \N      \N      \N      \N      \N      
\N      \N
+23     04-23-10        1       1       1       1       1.0     1       1       
\N      \N
+24     02-24-10-21     1       \N      \N      \N      \N      \N      \N      
\N      \N
+24     02-24-10-21     1       1       1       1       1.0     1       1       
\N      \N
+
+-- !select_default_nullable_old_planner --
+21     04-21-11        1       1       1       2       1.0     1       1       
\N      1
+21     04-21-11        1       1       1       2       1.0     1       1       
1       \N
+22     04-22-10-21     0       0       1       1       0.5     1       0       
\N      1
+22     04-22-10-21     0       1       1       2       0.6666666666666666      
1       0       1       1
+22     04-22-10-21     1       0       0       1       0.3333333333333333      
1       0       0       0
+22     04-22-10-21     1       0       1       1       0.5     1       0       
0       \N
+23     04-23-10        1       1       1       2       1.0     1       1       
\N      1
+23     04-23-10        1       1       1       2       1.0     1       1       
1       \N
+24     02-24-10-21     1       1       1       2       1.0     1       1       
\N      1
+24     02-24-10-21     1       1       1       2       1.0     1       1       
1       \N
+
+-- !select_empty_window_nullable_old_planner --
+21     04-21-11        1       \N      \N      \N      \N      \N      \N      
\N      \N
+21     04-21-11        1       1       1       1       1.0     1       1       
\N      \N
+22     04-22-10-21     0       \N      \N      \N      \N      \N      \N      
\N      0
+22     04-22-10-21     0       1       1       1       1.0     1       1       
0       \N
+22     04-22-10-21     1       0       0       0       0.0     0       0       
\N      1
+22     04-22-10-21     1       0       0       0       0.0     0       0       
1       \N
+23     04-23-10        1       \N      \N      \N      \N      \N      \N      
\N      \N
+23     04-23-10        1       1       1       1       1.0     1       1       
\N      \N
+24     02-24-10-21     1       \N      \N      \N      \N      \N      \N      
\N      \N
+24     02-24-10-21     1       1       1       1       1.0     1       1       
\N      \N
+
diff --git a/regression-test/data/correctness_p0/test_first_value_window.out 
b/regression-test/data/correctness_p0/test_first_value_window.out
index cabae5b19ab..9951ad95c60 100644
--- a/regression-test/data/correctness_p0/test_first_value_window.out
+++ b/regression-test/data/correctness_p0/test_first_value_window.out
@@ -20,3 +20,24 @@
 23     04-23-10        ["p7", "year4"] \N      \N
 24     02-24-10-21     [""]    \N      \N
 
+-- !select_default2 --
+21     04-21-11        1       1       1       1
+22     04-22-10-21     0       0       0       0
+22     04-22-10-21     1       0       0       0
+23     04-23-10        1       1       1       1
+24     02-24-10-21     1       1       1       1
+
+-- !select_default3 --
+1      21      04-21-11        \N      \N      \N      2
+2      21      04-21-12        2       \N      \N      2
+3      21      04-21-13        3       2       2       2
+4      22      04-22-10-21     \N      \N      \N      \N
+5      22      04-22-10-22     \N      \N      \N      5
+6      22      04-22-10-23     5       \N      \N      5
+7      22      04-22-10-24     \N      5       5       5
+8      22      04-22-10-25     9       \N      \N      9
+9      23      04-23-11        \N      \N      \N      10
+10     23      04-23-12        10      \N      \N      10
+11     23      04-23-13        \N      10      10      10
+12     24      02-24-10-21     \N      \N      \N      \N
+
diff --git a/regression-test/data/correctness_p0/test_first_value_window.out 
b/regression-test/data/correctness_p0/test_first_value_window_legacy_planner.out
similarity index 59%
copy from regression-test/data/correctness_p0/test_first_value_window.out
copy to 
regression-test/data/correctness_p0/test_first_value_window_legacy_planner.out
index cabae5b19ab..9951ad95c60 100644
--- a/regression-test/data/correctness_p0/test_first_value_window.out
+++ 
b/regression-test/data/correctness_p0/test_first_value_window_legacy_planner.out
@@ -20,3 +20,24 @@
 23     04-23-10        ["p7", "year4"] \N      \N
 24     02-24-10-21     [""]    \N      \N
 
+-- !select_default2 --
+21     04-21-11        1       1       1       1
+22     04-22-10-21     0       0       0       0
+22     04-22-10-21     1       0       0       0
+23     04-23-10        1       1       1       1
+24     02-24-10-21     1       1       1       1
+
+-- !select_default3 --
+1      21      04-21-11        \N      \N      \N      2
+2      21      04-21-12        2       \N      \N      2
+3      21      04-21-13        3       2       2       2
+4      22      04-22-10-21     \N      \N      \N      \N
+5      22      04-22-10-22     \N      \N      \N      5
+6      22      04-22-10-23     5       \N      \N      5
+7      22      04-22-10-24     \N      5       5       5
+8      22      04-22-10-25     9       \N      \N      9
+9      23      04-23-11        \N      \N      \N      10
+10     23      04-23-12        10      \N      \N      10
+11     23      04-23-13        \N      10      10      10
+12     24      02-24-10-21     \N      \N      \N      \N
+
diff --git a/regression-test/data/correctness_p0/test_last_value_window.out 
b/regression-test/data/correctness_p0/test_last_value_window.out
index 2ca759725ee..5792ccb0aa5 100644
--- a/regression-test/data/correctness_p0/test_last_value_window.out
+++ b/regression-test/data/correctness_p0/test_last_value_window.out
@@ -13,3 +13,18 @@
 23     04-23-10        ["p7", "year4"] ["p7", "year4"]
 24     02-24-10-21     [""]    [""]
 
+-- !select_null --
+1      21      04-21-11        1       \N      1
+2      21      04-21-12        \N      \N      1
+3      21      04-21-13        \N      \N      \N
+4      22      04-22-10        0       8       8
+5      22      04-22-11        8       \N      8
+6      22      04-22-12        \N      \N      8
+7      23      04-23-13        \N      2       2
+8      23      04-23-14        2       \N      2
+9      23      04-23-15        \N      \N      2
+10     23      04-23-16        \N      \N      \N
+11     24      02-24-10-22     \N      9       9
+12     24      02-24-10-23     9       \N      9
+13     24      02-24-10-24     \N      \N      9
+
diff --git a/regression-test/data/correctness_p0/test_last_value_window.out 
b/regression-test/data/correctness_p0/test_last_value_window_legacy_planner.out
similarity index 60%
copy from regression-test/data/correctness_p0/test_last_value_window.out
copy to 
regression-test/data/correctness_p0/test_last_value_window_legacy_planner.out
index 2ca759725ee..5792ccb0aa5 100644
--- a/regression-test/data/correctness_p0/test_last_value_window.out
+++ 
b/regression-test/data/correctness_p0/test_last_value_window_legacy_planner.out
@@ -13,3 +13,18 @@
 23     04-23-10        ["p7", "year4"] ["p7", "year4"]
 24     02-24-10-21     [""]    [""]
 
+-- !select_null --
+1      21      04-21-11        1       \N      1
+2      21      04-21-12        \N      \N      1
+3      21      04-21-13        \N      \N      \N
+4      22      04-22-10        0       8       8
+5      22      04-22-11        8       \N      8
+6      22      04-22-12        \N      \N      8
+7      23      04-23-13        \N      2       2
+8      23      04-23-14        2       \N      2
+9      23      04-23-15        \N      \N      2
+10     23      04-23-16        \N      \N      \N
+11     24      02-24-10-22     \N      9       9
+12     24      02-24-10-23     9       \N      9
+13     24      02-24-10-24     \N      \N      9
+
diff --git 
a/regression-test/suites/correctness_p0/test_always_nullable_window_function.groovy
 
b/regression-test/suites/correctness_p0/test_always_nullable_window_function.groovy
index 1bb79e5cbe4..52e2f699a2d 100644
--- 
a/regression-test/suites/correctness_p0/test_always_nullable_window_function.groovy
+++ 
b/regression-test/suites/correctness_p0/test_always_nullable_window_function.groovy
@@ -16,6 +16,8 @@
 // under the License.
 
 suite("test_always_nullable_window_function") {
+    sql """ set enable_nereids_planner = true; """
+    sql """ set enable_fallback_to_original_planner = false; """
     def tableName = "test_always_nullable_window_function_table"
     def nullableTableName = "test_always_nullable_window_function_table"
 
diff --git 
a/regression-test/suites/correctness_p0/test_always_nullable_window_function.groovy
 
b/regression-test/suites/correctness_p0/test_always_nullable_window_function_legacy_planner.groovy
similarity index 93%
copy from 
regression-test/suites/correctness_p0/test_always_nullable_window_function.groovy
copy to 
regression-test/suites/correctness_p0/test_always_nullable_window_function_legacy_planner.groovy
index 1bb79e5cbe4..3c8194d05e0 100644
--- 
a/regression-test/suites/correctness_p0/test_always_nullable_window_function.groovy
+++ 
b/regression-test/suites/correctness_p0/test_always_nullable_window_function_legacy_planner.groovy
@@ -15,11 +15,11 @@
 // specific language governing permissions and limitations
 // under the License.
 
-suite("test_always_nullable_window_function") {
-    def tableName = "test_always_nullable_window_function_table"
-    def nullableTableName = "test_always_nullable_window_function_table"
+suite("test_always_nullable_window_function_legacy_planner") {
+    sql """ set enable_nereids_planner = false; """
 
-    sql "set enable_nereids_planner = 1"
+    def tableName = "test_always_nullable_window_function_table_legacy_planner"
+    def nullableTableName = 
"test_always_nullable_window_function_table_legacy_planner"
 
     sql """ DROP TABLE IF EXISTS ${tableName} """
     sql """
@@ -77,8 +77,8 @@ suite("test_always_nullable_window_function") {
             avg(state) over(partition by myday order by time_col rows BETWEEN 
1 preceding AND 1 following) avg_value,
             max(state) over(partition by myday order by time_col rows BETWEEN 
1 preceding AND 1 following) max_value,
             min(state) over(partition by myday order by time_col rows BETWEEN 
1 preceding AND 1 following) min_value,
-            lag(state, 0, null) over (partition by myday order by time_col) 
lag_value,
-            lead(state, 0, null) over (partition by myday order by time_col) 
lead_value
+            lag(state, 10, null) over (partition by myday order by time_col) 
lag_value,
+            lead(state, 10, null) over (partition by myday order by time_col) 
lead_value
         from ${tableName} order by myday, time_col, state;
     """
     qt_select_empty_window """
@@ -102,8 +102,8 @@ suite("test_always_nullable_window_function") {
             avg(state) over(partition by myday order by time_col rows BETWEEN 
1 preceding AND 1 following) avg_value,
             max(state) over(partition by myday order by time_col rows BETWEEN 
1 preceding AND 1 following) max_value,
             min(state) over(partition by myday order by time_col rows BETWEEN 
1 preceding AND 1 following) min_value,
-            lag(state, 0, null) over (partition by myday order by time_col) 
lag_value,
-            lead(state, 0, null) over (partition by myday order by time_col) 
lead_value
+            lag(state, 10, null) over (partition by myday order by time_col) 
lag_value,
+            lead(state, 10, null) over (partition by myday order by time_col) 
lead_value
         from ${nullableTableName} order by myday, time_col, state;
     """
     qt_select_empty_window_nullable """
@@ -121,7 +121,7 @@ suite("test_always_nullable_window_function") {
 
     sql "set enable_nereids_planner = 0"
 
-    qt_select_default_old_planer """
+    qt_select_default_old_planner """
         select *,
             first_value(state) over(partition by myday order by time_col rows 
BETWEEN 1 preceding AND 1 following) f_value,
             last_value(state) over(partition by myday order by time_col rows 
BETWEEN 1 preceding AND 1 following) l_value,
@@ -133,7 +133,7 @@ suite("test_always_nullable_window_function") {
             lead(state, 1, null) over (partition by myday order by time_col) 
lead_value
         from ${tableName} order by myday, time_col, state;
     """
-    qt_select_empty_window_old_planer """
+    qt_select_empty_window_old_planner """
         select *,
             first_value(state) over(partition by myday order by time_col rows 
BETWEEN 1 preceding AND 1 preceding) f_value,
             last_value(state) over(partition by myday order by time_col rows 
BETWEEN 1 preceding AND 1 preceding) l_value,
@@ -146,7 +146,7 @@ suite("test_always_nullable_window_function") {
         from ${tableName} order by myday, time_col, state;
     """
 
-    qt_select_default_nullable_old_planer """
+    qt_select_default_nullable_old_planner """
         select *,
             first_value(state) over(partition by myday order by time_col rows 
BETWEEN 1 preceding AND 1 following) f_value,
             last_value(state) over(partition by myday order by time_col rows 
BETWEEN 1 preceding AND 1 following) l_value,
@@ -158,7 +158,7 @@ suite("test_always_nullable_window_function") {
             lead(state, 1, null) over (partition by myday order by time_col) 
lead_value
         from ${nullableTableName} order by myday, time_col, state;
     """
-    qt_select_empty_window_nullable_old_planer """
+    qt_select_empty_window_nullable_old_planner """
         select *,
             first_value(state) over(partition by myday order by time_col rows 
BETWEEN 1 preceding AND 1 preceding) f_value,
             last_value(state) over(partition by myday order by time_col rows 
BETWEEN 1 preceding AND 1 preceding) l_value,
diff --git 
a/regression-test/suites/correctness_p0/test_first_value_window.groovy 
b/regression-test/suites/correctness_p0/test_first_value_window.groovy
index 25246445fbb..8d0a3097056 100644
--- a/regression-test/suites/correctness_p0/test_first_value_window.groovy
+++ b/regression-test/suites/correctness_p0/test_first_value_window.groovy
@@ -16,8 +16,10 @@
 // under the License.
 
 suite("test_first_value_window") {
-    def tableName = "test_first_value_window_state"
+    sql """ set enable_nereids_planner = true; """
+    sql """ set enable_fallback_to_original_planner = false; """
 
+    def tableName = "test_first_value_window_state"
 
     sql """ DROP TABLE IF EXISTS ${tableName} """
     sql """
@@ -81,4 +83,80 @@ suite("test_first_value_window") {
             last_value(999) over(partition by myday order by time_col rows  
between 1 preceding and 1 preceding) last_value
         from test_first_value_window_array order by myday, time_col;
     """
+
+    def tableName2 = "test_first_value_window_state_not_null"
+
+    sql """ DROP TABLE IF EXISTS ${tableName2} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName2} (
+            `myday` INT,
+            `time_col` VARCHAR(40) NOT NULL,
+            `state` INT NOT NULL
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`myday`,time_col,state)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`myday`) BUCKETS 2
+            PROPERTIES (
+            "replication_num" = "1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            );
+    """
+
+    sql """ INSERT INTO ${tableName2} VALUES
+            (21,"04-21-11",1),
+            (22,"04-22-10-21",0),
+            (22,"04-22-10-21",1),
+            (23,"04-23-10",1),
+            (24,"02-24-10-21",1); """
+
+    qt_select_default2 """
+        select *
+            ,first_value(state) over(partition by `myday` order by `time_col`) 
v1
+            ,first_value(state, 0) over(partition by `myday` order by 
`time_col`) v2
+            ,first_value(state, 1) over(partition by `myday` order by 
`time_col`) v3
+        from ${tableName2} order by `myday`, `time_col`, `state`;
+    """
+
+    def tableName3 = "test_first_value_window_state_ignore_null"
+
+    sql """ DROP TABLE IF EXISTS ${tableName3} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName3} (
+                `id` INT,
+                `myday` INT,
+                `time_col` VARCHAR(40) NOT NULL,
+                `state` INT
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`id`, `myday`)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`id`, `myday`) BUCKETS 4
+            PROPERTIES (
+            "replication_num" = "1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            );
+    """
+
+    sql """ INSERT INTO ${tableName3} VALUES
+            (1,21,"04-21-11",null),
+            (2,21,"04-21-12",2),
+            (3,21,"04-21-13",3),
+            (4,22,"04-22-10-21",null),
+            (5,22,"04-22-10-22",null),
+            (6,22,"04-22-10-23",5),
+            (7,22,"04-22-10-24",null),
+            (8,22,"04-22-10-25",9),
+            (9,23,"04-23-11",null),
+            (10,23,"04-23-12",10),
+            (11,23,"04-23-13",null),
+            (12,24,"02-24-10-21",null); """
+
+    qt_select_default3 """
+        select *
+            ,first_value(`state`) over(partition by `myday` order by 
`time_col` rows between 1 preceding and 1 following) v1
+            ,first_value(`state`, 0) over(partition by `myday` order by 
`time_col` rows between 1 preceding and 1 following) v2
+            ,first_value(`state`, 1) over(partition by `myday` order by 
`time_col` rows between 1 preceding and 1 following) v3
+        from ${tableName3} order by `id`, `myday`, `time_col`;
+    """
 }
diff --git 
a/regression-test/suites/correctness_p0/test_first_value_window_legacy_planner.groovy
 
b/regression-test/suites/correctness_p0/test_first_value_window_legacy_planner.groovy
new file mode 100644
index 00000000000..37d6e62c2f5
--- /dev/null
+++ 
b/regression-test/suites/correctness_p0/test_first_value_window_legacy_planner.groovy
@@ -0,0 +1,161 @@
+// 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.
+
+suite("test_first_value_window_legacy_planner") {
+    sql """ set enable_nereids_planner = false; """
+
+    def tableName = "test_first_value_window_state_legacy_planner"
+
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+            `myday` INT,
+            `time_col` VARCHAR(40) NOT NULL,
+            `state` INT
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`myday`,time_col,state)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`myday`) BUCKETS 2
+            PROPERTIES (
+            "replication_num" = "1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            );
+    """
+
+    sql """ INSERT INTO ${tableName} VALUES
+            (21,"04-21-11",1),
+            (22,"04-22-10-21",0),
+            (22,"04-22-10-21",1),
+            (23,"04-23-10",1),
+            (24,"02-24-10-21",1); """
+
+    qt_select_default """ select *,first_value(state) over(partition by myday 
order by time_col range between current row and unbounded following) from 
${tableName} order by myday, time_col, state; """
+
+
+    def tableName1 = "test_first_value_window_array_legacy_planner"
+
+    sql """ DROP TABLE IF EXISTS ${tableName1} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName1} (
+            `myday` INT,
+            `time_col` VARCHAR(40) NOT NULL,
+            `state` ARRAY<STRING>
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`myday`,time_col)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`myday`) BUCKETS 2
+            PROPERTIES (
+            "replication_num" = "1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            );
+    """
+
+    sql """ INSERT INTO ${tableName1} VALUES
+            (21,"04-21-11",["amory", "clever"]),
+            (22,"04-22-10-21",["is ", "cute", "tea"]),
+            (22,"04-22-10-21",["doris", "aws", "greate"]),
+            (23,"04-23-10", ["p7", "year4"]),
+            (24,"02-24-10-21",[""]); """
+
+    qt_select_default """ select *,first_value(state) over(partition by myday 
order by time_col range between current row and unbounded following) from 
${tableName1} order by myday, time_col; """
+
+    qt_select_always_nullable """
+        select
+            *,
+            first_value(1) over(partition by myday order by time_col rows  
between 1 preceding and 1 preceding) first_value,
+            last_value(999) over(partition by myday order by time_col rows  
between 1 preceding and 1 preceding) last_value
+        from test_first_value_window_array_legacy_planner order by myday, 
time_col;
+    """
+
+    def tableName2 = "test_first_value_window_state_not_null_legacy_planner"
+
+    sql """ DROP TABLE IF EXISTS ${tableName2} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName2} (
+            `myday` INT,
+            `time_col` VARCHAR(40) NOT NULL,
+            `state` INT NOT NULL
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`myday`,time_col,state)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`myday`) BUCKETS 2
+            PROPERTIES (
+            "replication_num" = "1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            );
+    """
+
+    sql """ INSERT INTO ${tableName2} VALUES
+            (21,"04-21-11",1),
+            (22,"04-22-10-21",0),
+            (22,"04-22-10-21",1),
+            (23,"04-23-10",1),
+            (24,"02-24-10-21",1); """
+
+    qt_select_default2 """
+        select *
+            ,first_value(state) over(partition by `myday` order by `time_col`) 
v1
+            ,first_value(state, 0) over(partition by `myday` order by 
`time_col`) v2
+            ,first_value(state, 1) over(partition by `myday` order by 
`time_col`) v3
+        from ${tableName2} order by `myday`, `time_col`, `state`;
+    """
+
+    def tableName3 = "test_first_value_window_state_ignore_null_legacy_planner"
+
+    sql """ DROP TABLE IF EXISTS ${tableName3} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName3} (
+                `id` INT,
+                `myday` INT,
+                `time_col` VARCHAR(40) NOT NULL,
+                `state` INT
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`id`, `myday`)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`id`, `myday`) BUCKETS 4
+            PROPERTIES (
+            "replication_num" = "1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            );
+    """
+
+    sql """ INSERT INTO ${tableName3} VALUES
+            (1,21,"04-21-11",null),
+            (2,21,"04-21-12",2),
+            (3,21,"04-21-13",3),
+            (4,22,"04-22-10-21",null),
+            (5,22,"04-22-10-22",null),
+            (6,22,"04-22-10-23",5),
+            (7,22,"04-22-10-24",null),
+            (8,22,"04-22-10-25",9),
+            (9,23,"04-23-11",null),
+            (10,23,"04-23-12",10),
+            (11,23,"04-23-13",null),
+            (12,24,"02-24-10-21",null); """
+
+    qt_select_default3 """
+        select *
+            ,first_value(`state`) over(partition by `myday` order by 
`time_col` rows between 1 preceding and 1 following) v1
+            ,first_value(`state`, 0) over(partition by `myday` order by 
`time_col` rows between 1 preceding and 1 following) v2
+            ,first_value(`state`, 1) over(partition by `myday` order by 
`time_col` rows between 1 preceding and 1 following) v3
+        from ${tableName3} order by `id`, `myday`, `time_col`;
+    """
+}
diff --git 
a/regression-test/suites/correctness_p0/test_last_value_window.groovy 
b/regression-test/suites/correctness_p0/test_last_value_window.groovy
index d9b4c5f0e5c..3f3633d2270 100644
--- a/regression-test/suites/correctness_p0/test_last_value_window.groovy
+++ b/regression-test/suites/correctness_p0/test_last_value_window.groovy
@@ -16,8 +16,10 @@
 // under the License.
 
 suite("test_last_value_window") {
-    def tableName = "test_last_value_window_state"
+    sql """ set enable_nereids_planner = true; """
+    sql """ set enable_fallback_to_original_planner = false; """
 
+    def tableName = "test_last_value_window_state"
 
     sql """ DROP TABLE IF EXISTS ${tableName} """
     sql """
@@ -74,5 +76,43 @@ suite("test_last_value_window") {
 
     qt_select_default """ select *,last_value(state) over(partition by myday 
order by time_col range between current row and unbounded following) from 
${tableName1} order by myday, time_col; """
 
+    def tableNameWithNull = "test_last_value_window_state_null"
+    sql """ DROP TABLE IF EXISTS ${tableNameWithNull} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableNameWithNull} (
+                `id` INT,
+                `myday` INT,
+                `time_col` VARCHAR(40) NOT NULL,
+                `state` INT
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`id`,`myday`)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`id`) BUCKETS 4
+            PROPERTIES (
+            "replication_num" = "1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            );
+    """
+
+    sql """ INSERT INTO ${tableNameWithNull} VALUES 
+            (1,21,"04-21-11",1),
+            (2,21,"04-21-12",null),
+            (3,21,"04-21-13",null),
+            (4,22,"04-22-10",0),
+            (5,22,"04-22-11",8),
+            (6,22,"04-22-12",null),
+            (7,23,"04-23-13",null),
+            (8,23,"04-23-14",2),
+            (9,23,"04-23-15",null),
+            (10,23,"04-23-16",null),
+            (11,24,"02-24-10-22",null),
+            (12,24,"02-24-10-23",9),
+            (13,24,"02-24-10-24",null); """
 
+    qt_select_null """ select *
+                , last_value(state, false) over(partition by myday order by 
time_col rows between 1 preceding and 1 following) v1
+                , last_value(state, true) over(partition by myday order by 
time_col rows between 1 preceding and 1 following) v2
+            from ${tableNameWithNull} order by id, myday, time_col;
+        """
 }
diff --git 
a/regression-test/suites/correctness_p0/test_last_value_window.groovy 
b/regression-test/suites/correctness_p0/test_last_value_window_legacy_planner.groovy
similarity index 59%
copy from regression-test/suites/correctness_p0/test_last_value_window.groovy
copy to 
regression-test/suites/correctness_p0/test_last_value_window_legacy_planner.groovy
index d9b4c5f0e5c..de20441dcc9 100644
--- a/regression-test/suites/correctness_p0/test_last_value_window.groovy
+++ 
b/regression-test/suites/correctness_p0/test_last_value_window_legacy_planner.groovy
@@ -15,9 +15,10 @@
 // specific language governing permissions and limitations
 // under the License.
 
-suite("test_last_value_window") {
-    def tableName = "test_last_value_window_state"
+suite("test_last_value_window_legacy_planner") {
+    sql """ set enable_nereids_planner = false; """
 
+    def tableName = "test_last_value_window_state_legacy_planner"
 
     sql """ DROP TABLE IF EXISTS ${tableName} """
     sql """
@@ -36,7 +37,7 @@ suite("test_last_value_window") {
             );
     """
 
-    sql """ INSERT INTO ${tableName} VALUES 
+    sql """ INSERT INTO ${tableName} VALUES
             (21,"04-21-11",1),
             (22,"04-22-10-21",0),
             (22,"04-22-10-21",1),
@@ -46,7 +47,7 @@ suite("test_last_value_window") {
     qt_select_default """ select *,last_value(state) over(partition by myday 
order by time_col) from ${tableName} order by myday, time_col, state; """
 
 
-    def tableName1 = "test_last_value_window_array"
+    def tableName1 = "test_last_value_window_array_legacy_planner"
 
     sql """ DROP TABLE IF EXISTS ${tableName1} """
     sql """
@@ -74,5 +75,43 @@ suite("test_last_value_window") {
 
     qt_select_default """ select *,last_value(state) over(partition by myday 
order by time_col range between current row and unbounded following) from 
${tableName1} order by myday, time_col; """
 
+    def tableNameWithNull = "test_last_value_window_state_null_legacy_planner"
+    sql """ DROP TABLE IF EXISTS ${tableNameWithNull} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableNameWithNull} (
+                `id` INT,
+                `myday` INT,
+                `time_col` VARCHAR(40) NOT NULL,
+                `state` INT
+            ) ENGINE=OLAP
+            DUPLICATE KEY(`id`,`myday`)
+            COMMENT "OLAP"
+            DISTRIBUTED BY HASH(`id`) BUCKETS 4
+            PROPERTIES (
+            "replication_num" = "1",
+            "in_memory" = "false",
+            "storage_format" = "V2"
+            );
+    """
+
+    sql """ INSERT INTO ${tableNameWithNull} VALUES
+            (1,21,"04-21-11",1),
+            (2,21,"04-21-12",null),
+            (3,21,"04-21-13",null),
+            (4,22,"04-22-10",0),
+            (5,22,"04-22-11",8),
+            (6,22,"04-22-12",null),
+            (7,23,"04-23-13",null),
+            (8,23,"04-23-14",2),
+            (9,23,"04-23-15",null),
+            (10,23,"04-23-16",null),
+            (11,24,"02-24-10-22",null),
+            (12,24,"02-24-10-23",9),
+            (13,24,"02-24-10-24",null); """
 
+    qt_select_null """ select *
+                , last_value(state, false) over(partition by myday order by 
time_col rows between 1 preceding and 1 following) v1
+                , last_value(state, true) over(partition by myday order by 
time_col rows between 1 preceding and 1 following) v2
+            from ${tableNameWithNull} order by id, myday, time_col;
+        """
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to