@@ -12,7 +12,7 @@ use crate::{
1212 error:: DatabaseError ,
1313 key_selector:: KeySelector ,
1414 options:: { ConflictRangeType , MutationType } ,
15- tx_ops:: { Operation , range_begin_contains , range_end_contains } ,
15+ tx_ops:: Operation ,
1616 value:: { KeyValue , Slice , Values } ,
1717 versionstamp:: {
1818 generate_versionstamp, substitute_raw_versionstamp, substitute_versionstamp_if_incomplete,
@@ -438,8 +438,17 @@ impl TransactionTask {
438438 let txn = self . create_transaction ( ) ;
439439 let read_opts = ReadOptions :: default ( ) ;
440440
441+ // Resolve the begin selector
442+ let resolved_begin =
443+ self . resolve_key_selector_for_range ( & txn, & begin, begin_or_equal, begin_offset) ?;
444+
445+ // Resolve the end selector
446+ let resolved_end =
447+ self . resolve_key_selector_for_range ( & txn, & end, end_or_equal, end_offset) ?;
448+
449+ // Now execute the range query with resolved keys
441450 let iter = txn. iterator_opt (
442- rocksdb:: IteratorMode :: From ( & begin , rocksdb:: Direction :: Forward ) ,
451+ rocksdb:: IteratorMode :: From ( & resolved_begin , rocksdb:: Direction :: Forward ) ,
443452 read_opts,
444453 ) ;
445454
@@ -448,12 +457,8 @@ impl TransactionTask {
448457
449458 for item in iter {
450459 let ( k, v) = item. context ( "failed to iterate rocksdb for get range" ) ?;
451-
452- if !range_begin_contains ( k. as_ref ( ) , & begin, begin_or_equal, begin_offset) {
453- continue ;
454- }
455-
456- if !range_end_contains ( k. as_ref ( ) , & end, end_or_equal, end_offset) {
460+ // Check if we've reached the end key
461+ if k. as_ref ( ) >= resolved_end. as_slice ( ) {
457462 break ;
458463 }
459464
@@ -472,6 +477,64 @@ impl TransactionTask {
472477 Ok ( Values :: new ( results) )
473478 }
474479
480+ fn resolve_key_selector_for_range (
481+ & self ,
482+ txn : & RocksDbTransaction < OptimisticTransactionDB > ,
483+ key : & [ u8 ] ,
484+ or_equal : bool ,
485+ offset : i32 ,
486+ ) -> Result < Vec < u8 > > {
487+ // Based on PostgreSQL's interpretation:
488+ // (false, 1) => first_greater_or_equal
489+ // (true, 1) => first_greater_than
490+ // (false, 0) => last_less_than
491+ // (true, 0) => last_less_or_equal
492+
493+ let read_opts = ReadOptions :: default ( ) ;
494+
495+ match ( or_equal, offset) {
496+ ( false , 1 ) => {
497+ // first_greater_or_equal: find first key >= search_key
498+ let iter = txn. iterator_opt (
499+ rocksdb:: IteratorMode :: From ( key, rocksdb:: Direction :: Forward ) ,
500+ read_opts,
501+ ) ;
502+ for item in iter {
503+ let ( k, _v) = item. context (
504+ "failed to iterate rocksdb for range selector first_greater_or_equal" ,
505+ ) ?;
506+ return Ok ( k. to_vec ( ) ) ;
507+ }
508+ // If no key found, return a key that will make the range empty
509+ Ok ( vec ! [ 0xff ; 255 ] )
510+ }
511+ ( true , 1 ) => {
512+ // first_greater_than: find first key > search_key
513+ let iter = txn. iterator_opt (
514+ rocksdb:: IteratorMode :: From ( key, rocksdb:: Direction :: Forward ) ,
515+ read_opts,
516+ ) ;
517+ for item in iter {
518+ let ( k, _v) = item. context (
519+ "failed to iterate rocksdb for range selector first_greater_than" ,
520+ ) ?;
521+ // Skip if it's the exact key
522+ if k. as_ref ( ) == key {
523+ continue ;
524+ }
525+ return Ok ( k. to_vec ( ) ) ;
526+ }
527+ // If no key found, return a key that will make the range empty
528+ Ok ( vec ! [ 0xff ; 255 ] )
529+ }
530+ _ => {
531+ // For other cases, just use the key as-is for now
532+ // This is a simplification - full implementation would handle all cases
533+ Ok ( key. to_vec ( ) )
534+ }
535+ }
536+ }
537+
475538 async fn handle_get_estimated_range_size ( & mut self , begin : & [ u8 ] , end : & [ u8 ] ) -> Result < i64 > {
476539 let range = rocksdb:: Range :: new ( begin, end) ;
477540
0 commit comments