@@ -2,48 +2,67 @@ use std::os::raw::c_void;
22use std:: marker:: PhantomData ;
33use std:: ptr;
44
5+ use alloc:: MemoryContext ;
56use types:: Oid ;
67use error;
7- use Datum ;
8- use relation:: { Relation , RawTupleDesc , GetTransactionSnapshot } ;
8+ use relation:: { Relation , GetTransactionSnapshot } ;
99use tupledesc:: { TupleDesc , RefTupleDesc } ;
10+ use tupleslot:: { EmptyTupleSlot , TupleSlot } ;
1011
11- type HeapScanDesc = * mut c_void ;
12+ #[ repr( C ) ]
13+ struct HeapScanDescData {
14+ _pad : [ u8 ; :: RS_CBUF_OFFSET ] ,
15+ rs_cbuf : i32 ,
16+ }
17+ type HeapScanDesc = * mut HeapScanDescData ;
1218
19+ type HeapTupleData = c_void ;
1320extern "C" {
1421 fn heap_open ( relation : Oid , lockmode : i32 ) -> * const Relation ;
1522 fn relation_close ( relation : * const Relation , lockmode : i32 ) ;
1623
1724 fn heap_beginscan ( relation : * const Relation , snapshot : * mut c_void , nkeys : i32 , scankeys : * mut u8 ) -> HeapScanDesc ;
1825 //fn heap_rescan(scan: HeapScanDesc, scankeys: *mut u8);
19- fn heap_getnext ( scan : HeapScanDesc , direction : i32 ) -> * const HeapTupleData < ' static > ;
26+ fn heap_getnext ( scan : HeapScanDesc , direction : i32 ) -> * const HeapTupleData ;
2027 fn heap_endscan ( scan : HeapScanDesc ) ;
2128
22- fn heap_deform_tuple ( tuple : * const HeapTupleData , desc : * const RawTupleDesc , values : * mut Datum , isnull : * mut bool ) ;
29+ // fn heap_deform_tuple(tuple: *const HeapTupleData, desc: *const RawTupleDesc, values: *mut Datum, isnull: *mut bool);
2330}
2431
32+
33+
2534// FIXME private member
2635pub struct Heap ( pub ( crate ) * const Relation ) ;
27- pub struct HeapScan < ' a > {
36+ pub struct RawHeapScan < ' a > {
2837 ptr : HeapScanDesc ,
29- tupledesc : * const RawTupleDesc ,
3038 marker : PhantomData < & ' a Heap > ,
3139}
3240
41+ pub struct HeapScan < ' alloc , ' h > {
42+ raw : RawHeapScan < ' h > ,
43+ slot : EmptyTupleSlot < ' alloc , RefTupleDesc < ' h > > ,
44+ }
45+
3346impl Heap {
3447 pub fn open ( oid : Oid ) -> Heap {
3548 unsafe {
3649 error:: convert_postgres_error ( || Heap ( heap_open ( oid, 1 ) ) )
3750 }
3851 }
3952
40- pub fn scan ( & self ) -> HeapScan {
53+ pub fn scan < ' alloc , ' h > ( & ' h self , alloc : & ' alloc MemoryContext < ' alloc > ) -> HeapScan < ' alloc , ' h > {
54+ HeapScan {
55+ raw : self . scan_raw ( ) ,
56+ slot : EmptyTupleSlot :: create ( self . tuple_desc ( ) , alloc) ,
57+ }
58+ }
59+
60+ pub fn scan_raw < ' a > ( & ' a self ) -> RawHeapScan < ' a > {
4161 error:: convert_postgres_error ( || {
4262 unsafe {
4363 let snap = GetTransactionSnapshot ( ) ;
44- HeapScan {
64+ RawHeapScan {
4565 ptr : heap_beginscan ( self . 0 , snap, 0 , ptr:: null_mut ( ) ) ,
46- tupledesc : ( * self . 0 ) . td ,
4766 marker : PhantomData ,
4867 }
4968 }
@@ -57,77 +76,36 @@ impl Heap {
5776 }
5877}
5978
60-
61-
62- // TODO: verify in build that C compiler is capable of aligning
63- #[ repr( C ) ]
64- #[ derive( Clone , Copy ) ]
65- struct ItemPointerData {
66- foo : [ u8 ; 6 ]
67- }
68-
69-
70- #[ repr( C ) ]
71- struct HeapTupleHeader {
72- pad : [ u8 ; 22 ] ,
73- //pad: [u8; RELATT_OFFSET],
74- t_hoff : u8 ,
75- // tail ...
76- }
77-
78- pub struct HeapTuple < ' a > {
79- pub ( crate ) data : HeapTupleData < ' a > ,
80- pub ( crate ) tupledesc : * const RawTupleDesc ,
81- }
82-
83- // FIXME: make private
84- #[ repr( C ) ]
85- #[ derive( Clone , Copy ) ]
86- pub ( crate ) struct HeapTupleData < ' a > {
87- t_len : u32 ,
88- t_self : ItemPointerData ,
89- t_tableOid : Oid ,
90- t_data : & ' a HeapTupleHeader ,
91- }
92-
93-
94- impl < ' a > HeapTuple < ' a > {
95- pub fn deform ( & self ) -> Vec < Option < Datum < ' a > > > {
79+ impl < ' alloc , ' h > HeapScan < ' alloc , ' h > {
80+ pub fn next < ' a > ( & ' a mut self ) -> Option < TupleSlot < ' alloc , ' a , ' h , RefTupleDesc < ' h > > > {
9681 unsafe {
97- error:: convert_postgres_error ( || {
98- let natts = ( * self . tupledesc ) . natts as usize ;
99- let mut vals: Vec < Datum > = Vec :: with_capacity ( natts) ;
100- let mut flags: Vec < bool > = Vec :: with_capacity ( natts) ;
101- vals. set_len ( natts) ;
102- flags. set_len ( natts) ;
103-
104- heap_deform_tuple ( & self . data , self . tupledesc , vals. as_mut_ptr ( ) , flags. as_mut_ptr ( ) ) ;
105-
106- vals. into_iter ( ) . zip ( flags) . map ( |( v, f) | if f { None } else { Some ( v) } ) . collect ( )
107- } )
82+ match self . raw . next ( ) {
83+ None => None ,
84+ Some ( tuple) => {
85+ let buffer = ( * self . raw . ptr ) . rs_cbuf ;
86+ Some ( self . slot . store_tuple ( tuple, buffer) )
87+ }
88+ }
10889 }
10990 }
11091}
11192
112- impl < ' a > Iterator for HeapScan < ' a > {
113- type Item = HeapTuple < ' a > ;
93+ impl < ' a > Iterator for RawHeapScan < ' a > {
94+ type Item = * const HeapTupleData ;
11495
11596 fn next ( & mut self ) -> Option < Self :: Item > {
11697 unsafe {
11798 let tuple = error:: convert_postgres_error ( || heap_getnext ( self . ptr , 1 ) ) ;
11899 if tuple. is_null ( ) {
119100 None
120101 } else {
121- Some ( HeapTuple {
122- data : * tuple,
123- tupledesc : self . tupledesc ,
124- } )
102+ Some ( tuple)
125103 }
126104 }
127105 }
128106}
129107
130- impl < ' a > Drop for HeapScan < ' a > {
108+ impl < ' a > Drop for RawHeapScan < ' a > {
131109 fn drop ( & mut self ) {
132110 unsafe {
133111 error:: convert_postgres_error_dtor ( || heap_endscan ( self . ptr ) )
@@ -142,31 +120,3 @@ impl Drop for Heap {
142120 }
143121 }
144122}
145- /*
146- pub fn do_index_scan(rel: Oid, idx: Oid) -> i32 {
147- let mut counter = 0;
148- unsafe {
149- let heap = heap_open(rel, 1);
150- let index = index_open(idx, 1);
151-
152- let btint4cmp = 184;
153- let mut keybuf = [0u8; ::LEN_SCANKEYDATA];
154- ScanKeyInit(keybuf.as_mut_ptr(), 1, 3, btint4cmp, 4);
155-
156- let snap = GetTransactionSnapshot();
157- assert!(!snap.is_null());
158- let scan = index_beginscan(heap, index, snap, 1, 0);
159- index_rescan(scan, keybuf.as_mut_ptr(), 1, ptr::null_mut(), 0);
160- loop {
161- let thing = index_getnext(scan, 1);
162- if thing.is_null() { break; }
163- counter += 1;
164- }
165- index_endscan(scan);
166-
167- index_close(index, 1);
168- relation_close(heap, 1);
169- }
170- counter
171- }
172- */
0 commit comments