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

lgbo-ustc pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gluten.git


The following commit(s) were added to refs/heads/main by this push:
     new cb2c4ca157 [GLUTEN-12358][FLINK] Fix session lookup for parallel 
Gluten tasks (#12363)
cb2c4ca157 is described below

commit cb2c4ca157b409dcf1dd551aacd9a19e178c6db2
Author: kevinyhzou <[email protected]>
AuthorDate: Thu Jul 2 09:47:05 2026 +0800

    [GLUTEN-12358][FLINK] Fix session lookup for parallel Gluten tasks (#12363)
---
 .github/workflows/flink.yml                        |   2 +-
 gluten-flink/docs/Flink.md                         |   2 +-
 .../runtime/operators/GlutenOneInputOperator.java  |   5 +-
 ...onResources.java => GlutenSessionResource.java} |  26 ---
 .../runtime/operators/GlutenSourceFunction.java    |   3 +-
 .../operators/GlutenTaskSessionContext.java        |  68 ++++++++
 .../runtime/operators/GlutenTwoInputOperator.java  |   5 +-
 .../typeutils/GlutenStatefulRecordSerializer.java  |  27 +--
 .../GlutenStatefulRecordSerializerTest.java        | 184 +++++++++++++++++++++
 gluten-flink/ut/src/test/resources/nexmark/q12.sql |  20 +++
 10 files changed, 299 insertions(+), 43 deletions(-)

diff --git a/.github/workflows/flink.yml b/.github/workflows/flink.yml
index d2198a8cfa..656a08d5cf 100644
--- a/.github/workflows/flink.yml
+++ b/.github/workflows/flink.yml
@@ -88,7 +88,7 @@ jobs:
           export fmt_SOURCE=BUNDLED
           export folly_SOURCE=BUNDLED
           git clone -b gluten-0530 https://github.com/bigo-sg/velox4j.git
-          cd velox4j && git reset --hard 
97fc1edafebd0f505e613d260f77f92f5252d048
+          cd velox4j && git reset --hard 
9811c337d5e37ab8d16d5bf0791b48836fcd2afd
           git apply $GITHUB_WORKSPACE/gluten-flink/patches/fix-velox4j.patch
           $GITHUB_WORKSPACE/build/mvn clean install -DskipTests -Dgpg.skip 
-Dspotless.skip=true
           cd ..
diff --git a/gluten-flink/docs/Flink.md b/gluten-flink/docs/Flink.md
index 66387b782d..87f9a4e24b 100644
--- a/gluten-flink/docs/Flink.md
+++ b/gluten-flink/docs/Flink.md
@@ -48,7 +48,7 @@ As some features have not been committed to upstream, you 
have to use the follow
 ## fetch velox4j code
 git clone -b gluten-0530 https://github.com/bigo-sg/velox4j.git
 cd velox4j
-git reset --hard 97fc1edafebd0f505e613d260f77f92f5252d048
+git reset --hard 9811c337d5e37ab8d16d5bf0791b48836fcd2afd
 mvn clean install -DskipTests -Dgpg.skip -Dspotless.skip=true
 ```
 **Get gluten**
diff --git 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenOneInputOperator.java
 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenOneInputOperator.java
index 05645fda9a..09e2b2bb62 100644
--- 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenOneInputOperator.java
+++ 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenOneInputOperator.java
@@ -120,7 +120,7 @@ public class GlutenOneInputOperator<IN, OUT> extends 
TableStreamOperator<OUT>
       outputBridge = VectorOutputBridge.Factory.create(outClass);
     }
     sessionResource = new GlutenSessionResource();
-    GlutenSessionResources.getInstance().addSessionResource(id, 
sessionResource);
+    GlutenTaskSessionContext.addSessionResource(id, sessionResource);
     inputQueue = 
sessionResource.getSession().externalStreamOps().newBlockingQueue();
     // add a mock input as velox not allow the source is empty.
     if (inputType == null) {
@@ -283,6 +283,9 @@ public class GlutenOneInputOperator<IN, OUT> extends 
TableStreamOperator<OUT>
             inputQueue.close();
           }
         },
+        () -> {
+          GlutenTaskSessionContext.unregisterSessionResource(id);
+        },
         () -> {
           if (sessionResource != null) {
             sessionResource.close();
diff --git 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenSessionResources.java
 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenSessionResource.java
similarity index 76%
rename from 
gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenSessionResources.java
rename to 
gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenSessionResource.java
index cda410f719..ea38229e95 100644
--- 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenSessionResources.java
+++ 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenSessionResource.java
@@ -26,9 +26,6 @@ import org.apache.flink.runtime.state.KeyedStateBackend;
 import org.apache.arrow.memory.BufferAllocator;
 import org.apache.arrow.memory.RootAllocator;
 
-import java.util.HashMap;
-import java.util.Map;
-
 // Manage the session and resource for Velox.
 class GlutenSessionResource {
   private Session session;
@@ -77,26 +74,3 @@ class GlutenSessionResource {
     this.keyedStateBackend = keyedStateBackend;
   }
 }
-
-public class GlutenSessionResources {
-  private static final GlutenSessionResources instance = new 
GlutenSessionResources();
-  private Map<String, GlutenSessionResource> sessionResources = new 
HashMap<>();
-
-  private GlutenSessionResources() {}
-
-  public static GlutenSessionResources getInstance() {
-    return instance;
-  }
-
-  public GlutenSessionResource getSessionResource(String id) {
-    return sessionResources.get(id);
-  }
-
-  public void addSessionResource(String id, GlutenSessionResource 
sessionResource) {
-    sessionResources.put(id, sessionResource);
-  }
-
-  public Session getSession(String id) {
-    return sessionResources.get(id).getSession();
-  }
-}
diff --git 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenSourceFunction.java
 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenSourceFunction.java
index 19c7a69e99..5dfc8447a9 100644
--- 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenSourceFunction.java
+++ 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenSourceFunction.java
@@ -200,6 +200,7 @@ public class GlutenSourceFunction<OUT> extends 
RichParallelSourceFunction<OUT>
       task = null;
     }
     if (sessionResource != null) {
+      GlutenTaskSessionContext.unregisterSessionResource(id);
       sessionResource.close();
       sessionResource = null;
     }
@@ -241,7 +242,7 @@ public class GlutenSourceFunction<OUT> extends 
RichParallelSourceFunction<OUT>
     }
 
     sessionResource = new GlutenSessionResource();
-    GlutenSessionResources.getInstance().addSessionResource(id, 
sessionResource);
+    GlutenTaskSessionContext.addSessionResource(id, sessionResource);
     Session session = sessionResource.getSession();
     query =
         new Query(
diff --git 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenTaskSessionContext.java
 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenTaskSessionContext.java
new file mode 100644
index 0000000000..035567dd94
--- /dev/null
+++ 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenTaskSessionContext.java
@@ -0,0 +1,68 @@
+/*
+ * 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.gluten.table.runtime.operators;
+
+import io.github.zhztheplayer.velox4j.session.Session;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/** Task-thread-local Gluten runtime context used by operators and 
serializers. */
+public final class GlutenTaskSessionContext {
+  private static final ThreadLocal<Map<String, GlutenSessionResource>> 
SESSION_RESOURCES =
+      ThreadLocal.withInitial(HashMap::new);
+
+  private GlutenTaskSessionContext() {}
+
+  public static GlutenSessionResource getSessionResource(String id) {
+    return SESSION_RESOURCES.get().get(id);
+  }
+
+  public static void addSessionResource(String id, GlutenSessionResource 
sessionResource) {
+    SESSION_RESOURCES.get().put(id, sessionResource);
+  }
+
+  public static void registerSessionResource(String operatorId, 
GlutenSessionResource resource) {
+    addSessionResource(operatorId, resource);
+  }
+
+  public static void unregisterSessionResource(String operatorId) {
+    Map<String, GlutenSessionResource> resources = SESSION_RESOURCES.get();
+    resources.remove(operatorId);
+    if (resources.isEmpty()) {
+      SESSION_RESOURCES.remove();
+    }
+  }
+
+  public static Session getSession(String operatorId) {
+    Map<String, GlutenSessionResource> resources = SESSION_RESOURCES.get();
+    GlutenSessionResource resource = resources.get(operatorId);
+    if (resource == null) {
+      throw new IllegalStateException(
+          "No Gluten session registered on the current task thread for 
operator "
+              + operatorId
+              + ". Registered operators: "
+              + resources.keySet());
+    }
+    Session session = resource.getSession();
+    if (session == null) {
+      throw new IllegalStateException(
+          "Gluten session is already closed for operator " + operatorId);
+    }
+    return session;
+  }
+}
diff --git 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenTwoInputOperator.java
 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenTwoInputOperator.java
index 1251bb084e..7845e22a5b 100644
--- 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenTwoInputOperator.java
+++ 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/operators/GlutenTwoInputOperator.java
@@ -258,6 +258,9 @@ public class GlutenTwoInputOperator<IN, OUT> extends 
AbstractStreamOperator<OUT>
             task.close();
           }
         },
+        () -> {
+          GlutenTaskSessionContext.unregisterSessionResource(getId());
+        },
         () -> {
           if (sessionResource != null) {
             sessionResource.close();
@@ -324,7 +327,7 @@ public class GlutenTwoInputOperator<IN, OUT> extends 
AbstractStreamOperator<OUT>
     }
 
     sessionResource = new GlutenSessionResource();
-    GlutenSessionResources.getInstance().addSessionResource(getId(), 
sessionResource);
+    GlutenTaskSessionContext.addSessionResource(getId(), sessionResource);
     leftInputQueue = 
sessionResource.getSession().externalStreamOps().newBlockingQueue();
     rightInputQueue = 
sessionResource.getSession().externalStreamOps().newBlockingQueue();
 
diff --git 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/typeutils/GlutenStatefulRecordSerializer.java
 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/typeutils/GlutenStatefulRecordSerializer.java
index 66fdd7bc51..00e8abaab6 100644
--- 
a/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/typeutils/GlutenStatefulRecordSerializer.java
+++ 
b/gluten-flink/runtime/src/main/java/org/apache/gluten/table/runtime/typeutils/GlutenStatefulRecordSerializer.java
@@ -17,7 +17,7 @@
 package org.apache.gluten.table.runtime.typeutils;
 
 import org.apache.gluten.streaming.api.operators.GlutenOperator;
-import org.apache.gluten.table.runtime.operators.GlutenSessionResources;
+import org.apache.gluten.table.runtime.operators.GlutenTaskSessionContext;
 
 import io.github.zhztheplayer.velox4j.data.RowVector;
 import io.github.zhztheplayer.velox4j.stateful.StatefulRecord;
@@ -37,16 +37,20 @@ import java.io.IOException;
 public class GlutenStatefulRecordSerializer extends 
TypeSerializer<StatefulRecord> {
   private static final long serialVersionUID = 1L;
   private final RowType rowType;
-  private final GlutenOperator operator;
+  private final String operatorId;
 
   public GlutenStatefulRecordSerializer(RowType rowType, GlutenOperator 
operator) {
+    this(rowType, operator.getId());
+  }
+
+  private GlutenStatefulRecordSerializer(RowType rowType, String operatorId) {
     this.rowType = rowType;
-    this.operator = operator;
+    this.operatorId = operatorId;
   }
 
   @Override
   public TypeSerializer<StatefulRecord> duplicate() {
-    return new GlutenStatefulRecordSerializer(rowType, operator);
+    return new GlutenStatefulRecordSerializer(rowType, operatorId);
   }
 
   @Override
@@ -67,12 +71,11 @@ public class GlutenStatefulRecordSerializer extends 
TypeSerializer<StatefulRecor
     byte[] str = new byte[len];
     source.readFully(str);
     RowVector rowVector =
-        GlutenSessionResources.getInstance()
-            .getSession(operator.getId())
+        GlutenTaskSessionContext.getSession(operatorId)
             .baseVectorOps()
             .deserializeOne(new String(str))
             .asRowVector();
-    StatefulRecord record = new StatefulRecord(operator.getId(), 
rowVector.id(), 0, false, -1);
+    StatefulRecord record = new StatefulRecord(operatorId, rowVector.id(), 0, 
false, -1);
     record.setRowVector(rowVector);
     return record;
   }
@@ -130,7 +133,7 @@ public class GlutenStatefulRecordSerializer extends 
TypeSerializer<StatefulRecor
 
   @Override
   public TypeSerializerSnapshot<StatefulRecord> snapshotConfiguration() {
-    return new RowVectorSerializerSnapshot(rowType, operator);
+    return new RowVectorSerializerSnapshot(rowType, operatorId);
   }
 
   /** {@link TypeSerializerSnapshot} for Gluten RowVector.. */
@@ -139,16 +142,16 @@ public class GlutenStatefulRecordSerializer extends 
TypeSerializer<StatefulRecor
     private static final int CURRENT_VERSION = 1;
 
     private RowType rowType;
-    private GlutenOperator operator;
+    private String operatorId;
 
     @SuppressWarnings("unused")
     public RowVectorSerializerSnapshot() {
       // this constructor is used when restoring from a checkpoint/savepoint.
     }
 
-    RowVectorSerializerSnapshot(RowType rowType, GlutenOperator operator) {
+    RowVectorSerializerSnapshot(RowType rowType, String operatorId) {
       this.rowType = rowType;
-      this.operator = operator;
+      this.operatorId = operatorId;
     }
 
     @Override
@@ -165,7 +168,7 @@ public class GlutenStatefulRecordSerializer extends 
TypeSerializer<StatefulRecor
 
     @Override
     public GlutenStatefulRecordSerializer restoreSerializer() {
-      return new GlutenStatefulRecordSerializer(rowType, operator);
+      return new GlutenStatefulRecordSerializer(rowType, operatorId);
     }
 
     @Override
diff --git 
a/gluten-flink/ut/src/test/java/org/apache/gluten/table/runtime/operators/GlutenStatefulRecordSerializerTest.java
 
b/gluten-flink/ut/src/test/java/org/apache/gluten/table/runtime/operators/GlutenStatefulRecordSerializerTest.java
new file mode 100644
index 0000000000..4c38890446
--- /dev/null
+++ 
b/gluten-flink/ut/src/test/java/org/apache/gluten/table/runtime/operators/GlutenStatefulRecordSerializerTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.gluten.table.runtime.operators;
+
+import org.apache.gluten.streaming.api.operators.GlutenOperator;
+import org.apache.gluten.table.runtime.stream.common.Velox4jEnvironment;
+import 
org.apache.gluten.table.runtime.typeutils.GlutenStatefulRecordSerializer;
+import org.apache.gluten.util.LogicalTypeConverter;
+import org.apache.gluten.vectorized.FlinkRowToVLVectorConvertor;
+
+import io.github.zhztheplayer.velox4j.data.RowVector;
+import io.github.zhztheplayer.velox4j.plan.StatefulPlanNode;
+import io.github.zhztheplayer.velox4j.stateful.StatefulRecord;
+
+import org.apache.flink.core.memory.DataInputDeserializer;
+import org.apache.flink.core.memory.DataOutputSerializer;
+import org.apache.flink.table.data.GenericRowData;
+import org.apache.flink.table.data.RowData;
+import org.apache.flink.table.data.StringData;
+import org.apache.flink.table.types.logical.IntType;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.RowType;
+import org.apache.flink.table.types.logical.VarCharType;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class GlutenStatefulRecordSerializerTest {
+  private static final String OPERATOR_ID = "serializer-test-operator";
+
+  private GlutenSessionResource sourceResource;
+  private GlutenSessionResource targetResource;
+
+  @BeforeAll
+  public static void initializeVelox() {
+    Velox4jEnvironment.initializeOnce();
+  }
+
+  @AfterEach
+  public void tearDown() {
+    GlutenTaskSessionContext.unregisterSessionResource(OPERATOR_ID);
+    if (sourceResource != null) {
+      sourceResource.close();
+      sourceResource = null;
+    }
+    if (targetResource != null) {
+      targetResource.close();
+      targetResource = null;
+    }
+  }
+
+  @Test
+  public void testDeserializeUsesTaskLocalSession() throws Exception {
+    io.github.zhztheplayer.velox4j.type.RowType veloxRowType = 
createVeloxRowType();
+    GlutenStatefulRecordSerializer serializer =
+        new GlutenStatefulRecordSerializer(veloxRowType, new 
TestGlutenOperator(veloxRowType));
+
+    sourceResource = new GlutenSessionResource();
+    RowVector sourceVector =
+        FlinkRowToVLVectorConvertor.fromRowData(
+            GenericRowData.of(7, StringData.fromString("Alice")),
+            sourceResource.getAllocator(),
+            sourceResource.getSession(),
+            veloxRowType);
+    StatefulRecord sourceRecord = new StatefulRecord(OPERATOR_ID, 
sourceVector.id(), 0, false, 3);
+    sourceRecord.setRowVector(sourceVector);
+
+    DataOutputSerializer output = new DataOutputSerializer(128);
+    serializer.serialize(sourceRecord, output);
+
+    targetResource = new GlutenSessionResource();
+    GlutenTaskSessionContext.addSessionResource(OPERATOR_ID, targetResource);
+
+    StatefulRecord restoredRecord =
+        serializer.deserialize(new 
DataInputDeserializer(output.getCopyOfBuffer()));
+    List<RowData> restoredRows =
+        FlinkRowToVLVectorConvertor.toRowData(
+            restoredRecord.getRowVector(), targetResource.getAllocator(), 
veloxRowType);
+
+    assertThat(restoredRecord.getNodeId()).isEqualTo(OPERATOR_ID);
+    assertThat(restoredRows).hasSize(1);
+    RowData restoredRow = restoredRows.get(0);
+    assertThat(restoredRow.getInt(0)).isEqualTo(7);
+    
assertThat(restoredRow.getString(1)).isEqualTo(StringData.fromString("Alice"));
+
+    restoredRecord.close();
+    sourceRecord.close();
+  }
+
+  @Test
+  public void testTaskLocalSessionContextIsThreadIsolated() throws Exception {
+    ExecutorService executor = Executors.newFixedThreadPool(2);
+    CyclicBarrier barrier = new CyclicBarrier(2);
+    try {
+      Callable<Void> assertion =
+          () -> {
+            assertTaskLocalSessionIsIsolated(barrier);
+            return null;
+          };
+      Future<?> first = executor.submit(assertion);
+      Future<?> second = executor.submit(assertion);
+
+      first.get();
+      second.get();
+    } finally {
+      executor.shutdownNow();
+    }
+  }
+
+  private static void assertTaskLocalSessionIsIsolated(CyclicBarrier barrier) 
throws Exception {
+    GlutenSessionResource resource = new GlutenSessionResource();
+    try {
+      GlutenTaskSessionContext.addSessionResource(OPERATOR_ID, resource);
+      barrier.await();
+
+      
assertThat(GlutenTaskSessionContext.getSession(OPERATOR_ID)).isSameAs(resource.getSession());
+    } finally {
+      GlutenTaskSessionContext.unregisterSessionResource(OPERATOR_ID);
+      resource.close();
+    }
+  }
+
+  private static io.github.zhztheplayer.velox4j.type.RowType 
createVeloxRowType() {
+    RowType flinkRowType =
+        RowType.of(
+            new LogicalType[] {new IntType(), new 
VarCharType(VarCharType.MAX_LENGTH)},
+            new String[] {"id", "name"});
+    return (io.github.zhztheplayer.velox4j.type.RowType)
+        LogicalTypeConverter.toVLType(flinkRowType);
+  }
+
+  private static class TestGlutenOperator implements GlutenOperator {
+    private final io.github.zhztheplayer.velox4j.type.RowType rowType;
+
+    private TestGlutenOperator(io.github.zhztheplayer.velox4j.type.RowType 
rowType) {
+      this.rowType = rowType;
+    }
+
+    @Override
+    public StatefulPlanNode getPlanNode() {
+      return null;
+    }
+
+    @Override
+    public io.github.zhztheplayer.velox4j.type.RowType getInputType() {
+      return rowType;
+    }
+
+    @Override
+    public Map<String, io.github.zhztheplayer.velox4j.type.RowType> 
getOutputTypes() {
+      return Map.of(OPERATOR_ID, rowType);
+    }
+
+    @Override
+    public String getId() {
+      return OPERATOR_ID;
+    }
+  }
+}
diff --git a/gluten-flink/ut/src/test/resources/nexmark/q12.sql 
b/gluten-flink/ut/src/test/resources/nexmark/q12.sql
new file mode 100644
index 0000000000..f2cda4f463
--- /dev/null
+++ b/gluten-flink/ut/src/test/resources/nexmark/q12.sql
@@ -0,0 +1,20 @@
+CREATE TABLE nexmark_q12 (
+  bidder BIGINT,
+  bid_count BIGINT,
+  starttime TIMESTAMP(3),
+  endtime TIMESTAMP(3)
+) WITH (
+  'connector' = 'blackhole'
+);
+
+CREATE VIEW B AS SELECT *, PROCTIME() as p_time FROM bid;
+
+INSERT INTO nexmark_q12
+SELECT
+    bidder,
+    count(*) as bid_count,
+    window_start AS starttime,
+    window_end AS endtime
+FROM TABLE(
+        TUMBLE(TABLE B, DESCRIPTOR(p_time), INTERVAL '10' SECOND))
+GROUP BY bidder, window_start, window_end;


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

Reply via email to