From aaa8f18cb8639a6aed7d66f3041e9f5c593296e5 Mon Sep 17 00:00:00 2001 From: kasiafi <30203062+kasiafi@users.noreply.github.com> Date: Fri, 17 Oct 2025 19:20:38 +0200 Subject: [PATCH] Restrict logical navigations to running match --- .../pattern/LogicalIndexNavigation.java | 20 +++++++------------ .../sql/query/TestRowPatternMatching.java | 4 ++-- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/core/trino-main/src/main/java/io/trino/operator/window/pattern/LogicalIndexNavigation.java b/core/trino-main/src/main/java/io/trino/operator/window/pattern/LogicalIndexNavigation.java index e72e48304d47..e37260319986 100644 --- a/core/trino-main/src/main/java/io/trino/operator/window/pattern/LogicalIndexNavigation.java +++ b/core/trino-main/src/main/java/io/trino/operator/window/pattern/LogicalIndexNavigation.java @@ -76,26 +76,20 @@ public int resolvePosition(int currentRow, ArrayView matchedLabels, int searchSt checkArgument(currentRow >= patternStart && currentRow < patternStart + matchedLabels.length(), "current row is out of bounds of the match"); int relativePosition; + int patternEndInclusive = running ? currentRow - patternStart : matchedLabels.length() - 1; if (last) { - int start; - if (running) { - start = currentRow - patternStart; - } - else { - start = matchedLabels.length() - 1; - } - relativePosition = findLastAndBackwards(start, matchedLabels); + relativePosition = findLastAndBackwards(patternEndInclusive, matchedLabels); } else { - relativePosition = findFirstAndForward(matchedLabels); + relativePosition = findFirstAndForward(patternEndInclusive, matchedLabels); } return adjustPosition(relativePosition, patternStart, searchStart, searchEnd); } // LAST(A.price, 3): find the last occurrence of label "A" and go 3 occurrences backwards - private int findLastAndBackwards(int searchStart, ArrayView matchedLabels) + private int findLastAndBackwards(int patternEndInclusive, ArrayView matchedLabels) { - int position = searchStart + 1; + int position = patternEndInclusive + 1; int found = 0; while (found <= logicalOffset && position > 0) { position--; @@ -110,11 +104,11 @@ private int findLastAndBackwards(int searchStart, ArrayView matchedLabels) } // FIRST(A.price, 3): find the first occurrence of label "A" and go 3 occurrences forward - private int findFirstAndForward(ArrayView matchedLabels) + private int findFirstAndForward(int patternEndInclusive, ArrayView matchedLabels) { int position = -1; int found = 0; - while (found <= logicalOffset && position < matchedLabels.length() - 1) { + while (found <= logicalOffset && position < patternEndInclusive) { position++; if (labels.isEmpty() || labels.contains(matchedLabels.get(position))) { found++; diff --git a/core/trino-main/src/test/java/io/trino/sql/query/TestRowPatternMatching.java b/core/trino-main/src/test/java/io/trino/sql/query/TestRowPatternMatching.java index e0618766aa84..9121dfd51eab 100644 --- a/core/trino-main/src/test/java/io/trino/sql/query/TestRowPatternMatching.java +++ b/core/trino-main/src/test/java/io/trino/sql/query/TestRowPatternMatching.java @@ -1020,8 +1020,8 @@ public void testNavigationFunctions() assertThat(assertions.query(format(query, "FIRST(value, 2)"))) .matches("VALUES " + - " (1, 30), " + - " (2, 30), " + + " (1, null), " + + " (2, null), " + " (3, 30) "); assertThat(assertions.query(format(query, "LAST(value, 10)")))