github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/table/keyless_reader.go (about)

     1  // Copyright 2020 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  	"io"
    20  
    21  	"github.com/dolthub/go-mysql-server/sql"
    22  
    23  	"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
    24  	"github.com/dolthub/dolt/go/libraries/doltcore/row"
    25  	"github.com/dolthub/dolt/go/libraries/doltcore/schema"
    26  	"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil"
    27  	"github.com/dolthub/dolt/go/store/types"
    28  )
    29  
    30  type keylessTableReader struct {
    31  	iter types.MapIterator
    32  	sch  schema.Schema
    33  
    34  	row             row.Row
    35  	remainingCopies uint64
    36  }
    37  
    38  var _ SqlTableReader = &keylessTableReader{}
    39  var _ TableReadCloser = &keylessTableReader{}
    40  
    41  // GetSchema implements the TableReader interface.
    42  func (rdr *keylessTableReader) GetSchema() schema.Schema {
    43  	return rdr.sch
    44  }
    45  
    46  // ReadSqlRow implements the SqlTableReader interface.
    47  func (rdr *keylessTableReader) ReadRow(ctx context.Context) (row.Row, error) {
    48  	if rdr.remainingCopies <= 0 {
    49  		key, val, err := rdr.iter.Next(ctx)
    50  		if err != nil {
    51  			return nil, err
    52  		} else if key == nil {
    53  			return nil, io.EOF
    54  		}
    55  
    56  		rdr.row, rdr.remainingCopies, err = row.KeylessRowsFromTuples(key.(types.Tuple), val.(types.Tuple))
    57  		if err != nil {
    58  			return nil, err
    59  		}
    60  		if rdr.remainingCopies == 0 {
    61  			return nil, row.ErrZeroCardinality
    62  		}
    63  	}
    64  
    65  	rdr.remainingCopies -= 1
    66  
    67  	return rdr.row, nil
    68  }
    69  
    70  // ReadSqlRow implements the SqlTableReader interface.
    71  func (rdr *keylessTableReader) ReadSqlRow(ctx context.Context) (sql.Row, error) {
    72  	r, err := rdr.ReadRow(ctx)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	return sqlutil.DoltRowToSqlRow(r, rdr.sch)
    78  }
    79  
    80  // Close implements the TableReadCloser interface.
    81  func (rdr *keylessTableReader) Close(_ context.Context) error {
    82  	return nil
    83  }
    84  
    85  func newKeylessTableReader(ctx context.Context, tbl *doltdb.Table, sch schema.Schema, buffered bool) (*keylessTableReader, error) {
    86  	rows, err := tbl.GetRowData(ctx)
    87  	if err != nil {
    88  		return nil, err
    89  	}
    90  
    91  	return newKeylessTableReaderForRows(ctx, rows, sch, buffered)
    92  }
    93  
    94  func newKeylessTableReaderForRows(ctx context.Context, rows types.Map, sch schema.Schema, buffered bool) (*keylessTableReader, error) {
    95  	var err error
    96  	var iter types.MapIterator
    97  	if buffered {
    98  		iter, err = rows.Iterator(ctx)
    99  	} else {
   100  		iter, err = rows.BufferedIterator(ctx)
   101  	}
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	return &keylessTableReader{
   107  		iter: iter,
   108  		sch:  sch,
   109  	}, nil
   110  }
   111  
   112  // TODO: this is broken! (for partition boundaries that hit rows with cardinality > 1)
   113  func newKeylessTableReaderForPartition(ctx context.Context, tbl *doltdb.Table, sch schema.Schema, start, end uint64) (SqlTableReader, error) {
   114  	rows, err := tbl.GetRowData(ctx)
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  
   119  	iter, err := rows.BufferedIteratorAt(ctx, start)
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  
   124  	return &keylessTableReader{
   125  		iter: iter,
   126  		sch:  sch,
   127  	}, nil
   128  }
   129  
   130  func newKeylessTableReaderFrom(ctx context.Context, tbl *doltdb.Table, sch schema.Schema, val types.Value) (SqlTableReader, error) {
   131  	rows, err := tbl.GetRowData(ctx)
   132  	if err != nil {
   133  		return nil, err
   134  	}
   135  
   136  	iter, err := rows.IteratorFrom(ctx, val)
   137  	if err != nil {
   138  		return nil, err
   139  	}
   140  
   141  	return &keylessTableReader{
   142  		iter: iter,
   143  		sch:  sch,
   144  	}, nil
   145  }