Skip to content

Conversation

@i18nsite
Copy link
Contributor

English / 中文


Fix XPENDING Bug and Add Exclusive Range Support

Summary

This PR fixes a critical bug in the XPENDING command and implements the missing exclusive range support feature introduced in Redis 6.2.0.

Issues Fixed

Fixes #3276

Changes

1. Bug Fix: Empty Results When start_id == end_id

Problem: XPENDING incorrectly returned an empty list when querying a single entry (start_id equals end_id), even though the pending entry existed.

Root Causes:

  • Parsing Error: In cmd_stream.cc, CommandXPending::Parse incorrectly used start_id to parse the end_id parameter
  • Exclusive Upper Bound: In redis_stream.cc, GetPendingEntries used an exclusive upper bound for iteration, excluding entries at end_id

Fixes Applied:

  • Corrected the parsing logic to use end_id parameter correctly
  • Modified iteration bounds to be inclusive of end_id
  • Added optimization for single-entry lookup (direct Get instead of iteration)
  • Optimized loop comparison using rocksdb::Slice to avoid string allocation

2. Feature: Exclusive Range Support

Implementation: Added support for exclusive ranges using ( prefix as specified in Redis 6.2.0 documentation.

Changes:

  • Added exclude_start and exclude_end flags to StreamPendingOptions struct
  • Updated CommandXPending::Parse to detect and handle ( prefix
  • Modified GetPendingEntries iteration logic to respect exclusion flags

Usage Examples:

XPENDING mystream mygroup (1-0 +      # Exclude start
XPENDING mystream mygroup - (100-0    # Exclude end  
XPENDING mystream mygroup (1-0 (100-0 # Exclude both

Testing

Added comprehensive test suite in tests/gocase/unit/type/stream/xpending_test.go covering:

  • Bug reproduction case (start_id == end_id)
  • Summary form
  • Extended form with range and count
  • Consumer filtering
  • Idle time filtering
  • Exclusive ranges (all combinations)

All tests pass successfully.

Files Changed

  • src/commands/cmd_stream.cc: Fixed parsing and added exclusive range handling
  • src/types/redis_stream.cc: Fixed iteration bounds and optimized single-entry lookup
  • src/types/redis_stream_base.h: Added exclusion flags to StreamPendingOptions
  • tests/gocase/unit/type/stream/xpending_test.go: Comprehensive test coverage

修复 XPENDING 错误并添加排除范围支持

概述

本 PR 修复了 XPENDING 命令的一个严重错误,并实现了 Redis 6.2.0 中引入的排除范围功能。

修复的问题

修复 #3276

更改内容

1. 错误修复:当 start_id == end_id 时返回空结果

问题描述:当查询单个条目(start_id 等于 end_id)时,XPENDING 错误地返回空列表,即使待处理条目存在。

根本原因

  • 解析错误:在 cmd_stream.cc 中,CommandXPending::Parse 错误地使用 start_id 来解析 end_id 参数
  • 排除上界:在 redis_stream.cc 中,GetPendingEntries 使用了排除性的上界进行迭代,导致 end_id 处的条目被排除

应用的修复

  • 修正解析逻辑,正确使用 end_id 参数
  • 修改迭代边界,使其包含 end_id
  • 为单条目查询添加了优化(直接 Get 而非迭代)
  • 使用 rocksdb::Slice 优化循环比较以避免字符串分配

2. 功能:排除范围支持

实现内容:按照 Redis 6.2.0 文档的规范,使用 ( 前缀添加了排除范围支持。

变更

  • StreamPendingOptions 结构体中添加了 exclude_startexclude_end 标志
  • 更新 CommandXPending::Parse 以检测和处理 ( 前缀
  • 修改 GetPendingEntries 迭代逻辑以遵守排除标志

使用示例

XPENDING mystream mygroup (1-0 +      # 排除起始
XPENDING mystream mygroup - (100-0    # 排除结束
XPENDING mystream mygroup (1-0 (100-0 # 同时排除两端

测试

tests/gocase/unit/type/stream/xpending_test.go 中添加了全面的测试套件,涵盖:

  • 错误重现案例(start_id == end_id)
  • 摘要形式
  • 带范围和计数的扩展形式
  • 消费者过滤
  • 空闲时间过滤
  • 排除范围(所有组合)

所有测试均成功通过。

修改的文件

  • src/commands/cmd_stream.cc:修复解析并添加排除范围处理
  • src/types/redis_stream.cc:修复迭代边界并优化单条目查询
  • src/types/redis_stream_base.h:为 StreamPendingOptions 添加排除标志
  • tests/gocase/unit/type/stream/xpending_test.go:全面的测试覆盖

…#3276)

This commit fixes two issues with the XPENDING command:

1. Fixed bug where XPENDING returned empty results when start_id equals end_id
   - Fixed parsing error in CommandXPending::Parse where start_id was incorrectly
     used to parse end_id
   - Fixed iteration bounds in GetPendingEntries to be inclusive of end_id
   - Added optimization for single-entry lookup when start_id == end_id
   - Used rocksdb::Slice comparison to avoid string allocation in loop

2. Implemented exclusive range support as specified in Redis 6.2.0
   - Added exclude_start and exclude_end flags to StreamPendingOptions
   - Updated CommandXPending::Parse to handle '(' prefix for exclusive ranges
   - Updated GetPendingEntries iteration logic to respect exclusion flags

Tests:
- Added comprehensive test suite covering all XPENDING features
- All tests pass including bug reproduction, summary, extended form,
  consumer filter, idle filter, and exclusive ranges
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] xpending not include the end

1 participant