Jackie-Jiang commented on code in PR #14264: URL: https://github.com/apache/pinot/pull/14264#discussion_r1818210808
########## pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/window/value/FirstValueWindowFunction.java: ########## @@ -78,12 +86,73 @@ private List<Object> processRowsWindow(List<Object[]> rows) { lowerBound++; upperBound = Math.min(upperBound + 1, numRows - 1); } + + return result; + } + + private List<Object> processRowsWindowIgnoreNulls(List<Object[]> rows) { + int numRows = rows.size(); + int lowerBound = _windowFrame.getLowerBound(); + int upperBound = Math.min(_windowFrame.getUpperBound(), numRows - 1); + + int indexOfFirstNonNullValue = -1; + // Find first non-null value in the first window + for (int i = Math.max(lowerBound, 0); i <= upperBound; i++) { + Object value = extractValueFromRow(rows.get(i)); + if (value != null) { + indexOfFirstNonNullValue = i; + break; + } + } + + List<Object> result = new ArrayList<>(); Review Comment: ```suggestion List<Object> result = new ArrayList<>(numRows); ``` ########## pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/window/value/FirstValueWindowFunction.java: ########## @@ -78,12 +86,73 @@ private List<Object> processRowsWindow(List<Object[]> rows) { lowerBound++; upperBound = Math.min(upperBound + 1, numRows - 1); } + + return result; + } + + private List<Object> processRowsWindowIgnoreNulls(List<Object[]> rows) { Review Comment: Should we short circuit the unbounded case? ########## pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/window/value/FirstValueWindowFunction.java: ########## @@ -78,12 +86,73 @@ private List<Object> processRowsWindow(List<Object[]> rows) { lowerBound++; upperBound = Math.min(upperBound + 1, numRows - 1); } + + return result; + } + + private List<Object> processRowsWindowIgnoreNulls(List<Object[]> rows) { + int numRows = rows.size(); + int lowerBound = _windowFrame.getLowerBound(); + int upperBound = Math.min(_windowFrame.getUpperBound(), numRows - 1); + + int indexOfFirstNonNullValue = -1; + // Find first non-null value in the first window + for (int i = Math.max(lowerBound, 0); i <= upperBound; i++) { + Object value = extractValueFromRow(rows.get(i)); + if (value != null) { + indexOfFirstNonNullValue = i; + break; + } + } + + List<Object> result = new ArrayList<>(); + + for (int i = 0; i < numRows; i++) { + if (lowerBound >= numRows) { + // Fill the remaining rows with null + for (int j = i; j < numRows; j++) { + result.add(null); + } + break; + } + + if (indexOfFirstNonNullValue != -1) { + result.add(extractValueFromRow(rows.get(indexOfFirstNonNullValue))); + } else { + result.add(null); + } + + // Slide the window forward by one row + if (indexOfFirstNonNullValue == lowerBound) { Review Comment: Should we do this check only if `indexOfFirstNonNullValue != -1`? ########## pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/window/value/FirstValueWindowFunction.java: ########## @@ -78,12 +86,73 @@ private List<Object> processRowsWindow(List<Object[]> rows) { lowerBound++; upperBound = Math.min(upperBound + 1, numRows - 1); } + + return result; + } + + private List<Object> processRowsWindowIgnoreNulls(List<Object[]> rows) { + int numRows = rows.size(); + int lowerBound = _windowFrame.getLowerBound(); + int upperBound = Math.min(_windowFrame.getUpperBound(), numRows - 1); + + int indexOfFirstNonNullValue = -1; + // Find first non-null value in the first window + for (int i = Math.max(lowerBound, 0); i <= upperBound; i++) { + Object value = extractValueFromRow(rows.get(i)); + if (value != null) { + indexOfFirstNonNullValue = i; + break; + } + } + + List<Object> result = new ArrayList<>(); + + for (int i = 0; i < numRows; i++) { + if (lowerBound >= numRows) { + // Fill the remaining rows with null + for (int j = i; j < numRows; j++) { + result.add(null); + } + break; + } + + if (indexOfFirstNonNullValue != -1) { + result.add(extractValueFromRow(rows.get(indexOfFirstNonNullValue))); + } else { + result.add(null); + } + + // Slide the window forward by one row + if (indexOfFirstNonNullValue == lowerBound) { + indexOfFirstNonNullValue = -1; + // Find first non-null value for the next window + for (int j = Math.max(lowerBound + 1, 0); j <= Math.min(upperBound + 1, numRows - 1); j++) { + Object value = extractValueFromRow(rows.get(j)); + if (value != null) { + indexOfFirstNonNullValue = j; + break; + } + } + } + lowerBound++; + + if (upperBound < numRows - 1) { Review Comment: Some javadoc would help explain the logic here -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org