github.com/dolthub/dolt/go@v0.40.5-0.20240520175717-68db7794bea6/libraries/doltcore/table/table_iterator.go (about) 1 // Copyright 2022 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package table 16 17 import ( 18 "context" 19 20 "github.com/dolthub/go-mysql-server/sql" 21 22 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb/durable" 23 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 24 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/index" 25 "github.com/dolthub/dolt/go/store/types" 26 ) 27 28 // RowIter wraps a sql.RowIter and abstracts away sql.Context for a 29 // context.Context. 30 type RowIter interface { 31 Next(ctx context.Context) (sql.Row, error) 32 Close(ctx context.Context) error 33 } 34 35 type rowIterImpl struct { 36 inner sql.RowIter 37 sqlCtx *sql.Context 38 } 39 40 // NewRowIter returns a RowIter that wraps |inner|. Ctx passed to Next is 41 // converted to *sql.Context. 42 func NewRowIter(inner sql.RowIter) RowIter { 43 return rowIterImpl{inner: inner} 44 } 45 46 // Next implements RowIter. 47 func (i rowIterImpl) Next(ctx context.Context) (sql.Row, error) { 48 r, err := i.inner.Next(&sql.Context{Context: ctx}) 49 if err != nil { 50 return nil, err 51 } 52 return r, nil 53 } 54 55 // Close implements RowIter. 56 func (i rowIterImpl) Close(ctx context.Context) error { 57 return i.inner.Close(&sql.Context{Context: ctx}) 58 } 59 60 // NewTableIterator creates a RowIter that iterates sql.Row's from |idx|. 61 // |offset| can be supplied to read at some start point in |idx|. 62 func NewTableIterator(ctx context.Context, sch schema.Schema, idx durable.Index, offset uint64) (RowIter, error) { 63 var rowItr sql.RowIter 64 if types.IsFormat_DOLT(idx.Format()) { 65 m := durable.ProllyMapFromIndex(idx) 66 c, err := m.Count() 67 if err != nil { 68 return nil, err 69 } 70 itr, err := m.IterOrdinalRange(ctx, offset, uint64(c)) 71 if err != nil { 72 return nil, err 73 } 74 rowItr = index.NewProllyRowIterForMap(sch, m, itr, nil) 75 if err != nil { 76 return nil, err 77 } 78 } else { 79 80 noms := durable.NomsMapFromIndex(idx) 81 itr, err := noms.IteratorAt(ctx, offset) 82 if err != nil { 83 return nil, err 84 } 85 conv := makeNomsConverter(idx.Format(), sch) 86 rowItr = index.NewDoltMapIter(itr.NextTuple, nil, conv) 87 } 88 return NewRowIter(rowItr), nil 89 } 90 91 // makeNomsConverter creates a *index.KVToSqlRowConverter. 92 func makeNomsConverter(nbf *types.NomsBinFormat, sch schema.Schema) *index.KVToSqlRowConverter { 93 cols := sch.GetAllCols().GetColumns() 94 tagToSqlColIdx := make(map[uint64]int) 95 for i, col := range cols { 96 tagToSqlColIdx[col.Tag] = i 97 } 98 return index.NewKVToSqlRowConverter(nbf, tagToSqlColIdx, cols, len(cols)) 99 }