ronantakizawa/codereview-bench huggingface dataset:
Repository: codenotary/immudb
File: pkg/database/database.go (Go)

Code before:
	}

	dualProof, err := d.st.DualProof(sourceTx, targetTx)
	if err != nil {
		return nil, err
	}

	sReqTx, err := d.serializeTx(reqTx, req.EntriesSpec, snap)
	if err != nil {
		return nil, err
	}

	return &schema.VerifiableTx{
		Tx:        sReqTx,
		DualProof: schema.DualProofToProto(dualProof),
	}, nil
}

//TxScan ...
func (d *db) TxScan(req *schema.TxScanRequest) (*schema.TxList, error) {
	if req == nil {
		return nil, ErrIllegalArguments
	}

	if req.Limit > MaxKeyScanLimit {
		return nil, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitExceeded, MaxKeyScanLimit)
	}

	limit := int(req.Limit)

	if req.Limit == 0 {
		limit = MaxKeyScanLimit
	}

	snap, err := d.snapshotSince(req.SinceTx, req.NoWait)
	if err != nil {
		return nil, err
	}
	defer snap.Close()

	txReader, err := d.st.NewTxReader(req.InitialTx, req.Desc, d.st.NewTxHolder())
	if err != nil {
		return nil, err
	}

	txList := &schema.TxList{}

	for l := 1; l <= limit; l++ {
		tx, err := txReader.Read()
		if err == store.ErrNoMoreEntries {
			break

Review comment (suggestion):
```suggestion
		return nil, fmt.Errorf("%w: given limit (%d) is larger than the maximum allowed one (%d)", ErrMaxKeyScanLimitExceeded, req.Limit, MaxKeyScanLimit)
```

Code after:
		sourceTx = rootTx
		targetTx = reqTx
	} else {
		sourceTx = reqTx
		targetTx = rootTx
	}

	dualProof, err := d.st.DualProof(sourceTx, targetTx)
	if err != nil {
		return nil, err
	}

	sReqTx, err := d.serializeTx(reqTx, req.EntriesSpec, snap)
	if err != nil {
		return nil, err
	}

	return &schema.VerifiableTx{
		Tx:        sReqTx,
		DualProof: schema.DualProofToProto(dualProof),
	}, nil
}

//TxScan ...
func (d *db) TxScan(req *schema.TxScanRequest) (*schema.TxList, error) {
	if req == nil {
		return nil, ErrIllegalArguments
	}

	if int(req.Limit) > d.maxResultSize {
		return nil, fmt.Errorf("%w: the specified limit (%d) is larger than the maximum allowed one (%d)",
			ErrResultSizeLimitExceeded, req.Limit, d.maxResultSize)
	}

	limit := int(req.Limit)

	if req.Limit == 0 {
		limit = d.maxResultSize
	}

	snap, err := d.snapshotSince(req.SinceTx, req.NoWait)
	if err != nil {
		return nil, err
	}
	defer snap.Close()

	txReader, err := d.st.NewTxReader(req.InitialTx, req.Desc, d.st.NewTxHolder())
	if err != nil {
		return nil, err
	}
Repository: codenotary/immudb
File: pkg/database/database.go (Go)

Code before:

	txReader, err := d.st.NewTxReader(req.InitialTx, req.Desc, d.st.NewTxHolder())
	if err != nil {
		return nil, err
	}

	txList := &schema.TxList{}

	for l := 1; l <= limit; l++ {
		tx, err := txReader.Read()
		if err == store.ErrNoMoreEntries {
			break
		}
		if err != nil {
			return nil, err
		}

		sTx, err := d.serializeTx(tx, req.EntriesSpec, snap)
		if err != nil {
			return nil, err
		}

		txList.Txs = append(txList.Txs, sTx)

		if l == MaxKeyScanLimit {
			return txList, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
		}
	}

	return txList, nil
}

//History ...
func (d *db) History(req *schema.HistoryRequest) (*schema.Entries, error) {
	if req == nil {
		return nil, ErrIllegalArguments
	}

	if req.Limit > MaxKeyScanLimit {
		return nil, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitExceeded, MaxKeyScanLimit)
	}

	currTxID, _ := d.st.Alh()

	if req.SinceTx > currTxID {
		return nil, ErrIllegalArguments
	}

	waitUntilTx := req.SinceTx
	if waitUntilTx == 0 {
		waitUntilTx = currTxID

Review comment (suggestion):
```suggestion
			return txList, fmt.Errorf("%w: found more than %d entries (the maximum limit), please use the limit and initialTx arguments to paginate over large results", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
```

Code after:

	snap, err := d.snapshotSince(req.SinceTx, req.NoWait)
	if err != nil {
		return nil, err
	}
	defer snap.Close()

	txReader, err := d.st.NewTxReader(req.InitialTx, req.Desc, d.st.NewTxHolder())
	if err != nil {
		return nil, err
	}

	txList := &schema.TxList{}

	for l := 1; l <= limit; l++ {
		tx, err := txReader.Read()
		if err == store.ErrNoMoreEntries {
			break
		}
		if err != nil {
			return nil, err
		}

		sTx, err := d.serializeTx(tx, req.EntriesSpec, snap)
		if err != nil {
			return nil, err
		}

		txList.Txs = append(txList.Txs, sTx)

		if l == d.maxResultSize {
			return txList,
				fmt.Errorf("%w: found at least %d entries (maximum limit). "+
					"Pagination over large results can be achieved by using the limit and initialTx arguments",
					ErrResultSizeLimitReached, d.maxResultSize)
		}
	}

	return txList, nil
}

//History ...
func (d *db) History(req *schema.HistoryRequest) (*schema.Entries, error) {
	if req == nil {
		return nil, ErrIllegalArguments
	}

	if int(req.Limit) > d.maxResultSize {
		return nil, fmt.Errorf("%w: the specified limit (%d) is larger than the maximum allowed one (%d)",
			ErrResultSizeLimitExceeded, req.Limit, d.maxResultSize)
	}
Repository: codenotary/immudb
File: pkg/database/database.go (Go)

Code before:
			return nil, err
		}

		sTx, err := d.serializeTx(tx, req.EntriesSpec, snap)
		if err != nil {
			return nil, err
		}

		txList.Txs = append(txList.Txs, sTx)

		if l == MaxKeyScanLimit {
			return txList, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
		}
	}

	return txList, nil
}

//History ...
func (d *db) History(req *schema.HistoryRequest) (*schema.Entries, error) {
	if req == nil {
		return nil, ErrIllegalArguments
	}

	if req.Limit > MaxKeyScanLimit {
		return nil, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitExceeded, MaxKeyScanLimit)
	}

	currTxID, _ := d.st.Alh()

	if req.SinceTx > currTxID {
		return nil, ErrIllegalArguments
	}

	waitUntilTx := req.SinceTx
	if waitUntilTx == 0 {
		waitUntilTx = currTxID
	}

	err := d.WaitForIndexingUpto(waitUntilTx, nil)
	if err != nil {
		return nil, err
	}

	limit := int(req.Limit)

	if req.Limit == 0 {
		limit = MaxKeyScanLimit
	}

	key := EncodeKey(req.Key)

Review comment (suggestion):
```suggestion
		return nil, fmt.Errorf("%w: given limit (%d) is larger than the maximum allowed one (%d)", ErrMaxKeyScanLimitExceeded, req.Limit, MaxKeyScanLimit)
```

Code after:
	for l := 1; l <= limit; l++ {
		tx, err := txReader.Read()
		if err == store.ErrNoMoreEntries {
			break
		}
		if err != nil {
			return nil, err
		}

		sTx, err := d.serializeTx(tx, req.EntriesSpec, snap)
		if err != nil {
			return nil, err
		}

		txList.Txs = append(txList.Txs, sTx)

		if l == d.maxResultSize {
			return txList,
				fmt.Errorf("%w: found at least %d entries (maximum limit). "+
					"Pagination over large results can be achieved by using the limit and initialTx arguments",
					ErrResultSizeLimitReached, d.maxResultSize)
		}
	}

	return txList, nil
}

//History ...
func (d *db) History(req *schema.HistoryRequest) (*schema.Entries, error) {
	if req == nil {
		return nil, ErrIllegalArguments
	}

	if int(req.Limit) > d.maxResultSize {
		return nil, fmt.Errorf("%w: the specified limit (%d) is larger than the maximum allowed one (%d)",
			ErrResultSizeLimitExceeded, req.Limit, d.maxResultSize)
	}

	currTxID, _ := d.st.Alh()

	if req.SinceTx > currTxID {
		return nil, ErrIllegalArguments
	}

	waitUntilTx := req.SinceTx
	if waitUntilTx == 0 {
		waitUntilTx = currTxID
	}

	err := d.WaitForIndexingUpto(waitUntilTx, nil)
	if err != nil {
Repository: codenotary/immudb
File: pkg/database/database.go (Go)

Code before:
		val, err := d.st.ReadValue(entry)
		if err != nil && err != store.ErrExpiredEntry {
			return nil, err
		}
		if len(val) > 0 {
			val = TrimPrefix(val)
		}

		list.Entries[i] = &schema.Entry{
			Tx:       txID,
			Key:      req.Key,
			Metadata: schema.KVMetadataToProto(entry.Metadata()),
			Value:    val,
			Expired:  err == store.ErrExpiredEntry,
			Revision: revision,
		}

		if req.Desc {
			revision--
		} else {
			revision++
		}
	}

	if limit == MaxKeyScanLimit && hCount >= MaxKeyScanLimit {
		return list, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
	}

	return list, nil
}

func (d *db) IsClosed() bool {
	d.mutex.RLock()
	defer d.mutex.RUnlock()

	return d.st.IsClosed()
}

//Close ...
func (d *db) Close() (err error) {
	d.mutex.Lock()
	defer d.mutex.Unlock()

	d.Logger.Infof("Closing database '%s'...", d.name)

	defer func() {
		if err == nil {
			d.Logger.Infof("Database '%s' succesfully closed", d.name)
		} else {
			d.Logger.Infof("%v: while closing database '%s'", err, d.name)
		}

Review comment (suggestion):
```suggestion
			return list, fmt.Errorf("%w: found more than %d entries (the maximum limit), please use the limit and offset arguments to paginate over large results", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
```

Code after:
		err = d.st.ReadTx(txID, tx)
		if err != nil {
			return nil, err
		}

		entry, err := tx.EntryOf(key)
		if err != nil {
			return nil, err
		}

		val, err := d.st.ReadValue(entry)
		if err != nil && err != store.ErrExpiredEntry {
			return nil, err
		}
		if len(val) > 0 {
			val = TrimPrefix(val)
		}

		list.Entries[i] = &schema.Entry{
			Tx:       txID,
			Key:      req.Key,
			Metadata: schema.KVMetadataToProto(entry.Metadata()),
			Value:    val,
			Expired:  err == store.ErrExpiredEntry,
			Revision: revision,
		}

		if req.Desc {
			revision--
		} else {
			revision++
		}
	}

	if limit == d.maxResultSize && hCount >= uint64(d.maxResultSize) {
		return list,
			fmt.Errorf("%w: found at least %d entries (the maximum limit). "+
				"Pagination over large results can be achieved by using the limit and initialTx arguments",
				ErrResultSizeLimitReached, d.maxResultSize)
	}

	return list, nil
}

func (d *db) IsClosed() bool {
	d.mutex.RLock()
	defer d.mutex.RUnlock()

	return d.st.IsClosed()
}
Repository: codenotary/immudb
File: pkg/database/scan.go (Go)

Code before:
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package database

import (
	"fmt"

	"github.com/codenotary/immudb/embedded/store"
	"github.com/codenotary/immudb/pkg/api/schema"
)

//Scan ...
func (d *db) Scan(req *schema.ScanRequest) (*schema.Entries, error) {
	d.mutex.RLock()
	defer d.mutex.RUnlock()

	currTxID, _ := d.st.Alh()

	if req == nil || req.SinceTx > currTxID {
		return nil, store.ErrIllegalArguments
	}

	if req.Limit > MaxKeyScanLimit {
		return nil, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitExceeded, MaxKeyScanLimit)
	}

	waitUntilTx := req.SinceTx
	if waitUntilTx == 0 {
		waitUntilTx = currTxID
	}

	if !req.NoWait {
		err := d.st.WaitForIndexingUpto(waitUntilTx, nil)
		if err != nil {
			return nil, err
		}
	}

	limit := int(req.Limit)

	if req.Limit == 0 {
		limit = MaxKeyScanLimit
	}

	snap, err := d.st.SnapshotSince(waitUntilTx)
	if err != nil {
		return nil, err
	}
	defer snap.Close()

Review comment (suggestion):
```suggestion
		return nil, fmt.Errorf("%w: given limit (%d) is larger than the maximum allowed one (%d)", ErrMaxKeyScanLimitExceeded, req.Limit, MaxKeyScanLimit)
```

Code after:
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package database

import (
	"fmt"

	"github.com/codenotary/immudb/embedded/store"
	"github.com/codenotary/immudb/pkg/api/schema"
)

//Scan ...
func (d *db) Scan(req *schema.ScanRequest) (*schema.Entries, error) {
	d.mutex.RLock()
	defer d.mutex.RUnlock()

	currTxID, _ := d.st.Alh()

	if req == nil || req.SinceTx > currTxID {
		return nil, store.ErrIllegalArguments
	}

	if req.Limit > uint64(d.maxResultSize) {
		return nil, fmt.Errorf("%w: the specified limit (%d) is larger than the maximum allowed one (%d)",
			ErrResultSizeLimitExceeded, req.Limit, d.maxResultSize)
	}

	waitUntilTx := req.SinceTx
	if waitUntilTx == 0 {
		waitUntilTx = currTxID
	}

	if !req.NoWait {
		err := d.st.WaitForIndexingUpto(waitUntilTx, nil)
		if err != nil {
			return nil, err
		}
	}

	limit := int(req.Limit)

	if req.Limit == 0 {
		limit = d.maxResultSize
	}

	snap, err := d.st.SnapshotSince(waitUntilTx)
	if err != nil {
		return nil, err
	}
Repository: codenotary/immudb
File: pkg/database/scan.go (Go)

Code before:
	tx := d.st.NewTxHolder()

	entries := &schema.Entries{}

	for l := 1; l <= limit; l++ {
		key, valRef, err := r.Read()
		if err == store.ErrNoMoreEntries {
			break
		}
		if err != nil {
			return nil, err
		}

		e, err := d.getAtTx(key, valRef.Tx(), 0, snap, tx, 0)
		if err == store.ErrKeyNotFound {
			// ignore deleted ones (referenced key may have been deleted)
			continue
		}
		if err != nil {
			return nil, err
		}

		entries.Entries = append(entries.Entries, e)

		if l == MaxKeyScanLimit {
			return entries, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
		}
	}

	return entries, nil
}


Review comment (suggestion):
```suggestion
			return entries, fmt.Errorf("%w: found more than %d entries (the maximum limit), please use the limit and seekKey arguments to paginate over large results", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
```

Code after:
			Filters:       []store.FilterFn{store.IgnoreExpired, store.IgnoreDeleted},
			InclusiveSeek: req.InclusiveSeek,
			InclusiveEnd:  req.InclusiveEnd,
		})
	if err != nil {
		return nil, err
	}
	defer r.Close()

	tx := d.st.NewTxHolder()

	entries := &schema.Entries{}

	for l := 1; l <= limit; l++ {
		key, valRef, err := r.Read()
		if err == store.ErrNoMoreEntries {
			break
		}
		if err != nil {
			return nil, err
		}

		e, err := d.getAtTx(key, valRef.Tx(), 0, snap, tx, 0)
		if err == store.ErrKeyNotFound {
			// ignore deleted ones (referenced key may have been deleted)
			continue
		}
		if err != nil {
			return nil, err
		}

		entries.Entries = append(entries.Entries, e)

		if l == d.maxResultSize {
			return entries,
				fmt.Errorf("%w: found at least %d entries (the maximum limit). "+
					"Pagination over large results can be achieved by using the limit and initialTx arguments",
					ErrResultSizeLimitReached, d.maxResultSize)
		}
	}

	return entries, nil
}
Repository: codenotary/immudb
File: pkg/database/sorted_set.go (Go)

Code before:
	if err != nil {
		return nil, err
	}

	var hdr *store.TxHeader

	if req.NoWait {
		hdr, err = tx.AsyncCommit()
	} else {
		hdr, err = tx.Commit()
	}
	if err != nil {
		return nil, err
	}

	return schema.TxHeaderToProto(hdr), nil
}

// ZScan ...
func (d *db) ZScan(req *schema.ZScanRequest) (*schema.ZEntries, error) {
	if req == nil || len(req.Set) == 0 {
		return nil, store.ErrIllegalArguments
	}

	if req.Limit > MaxKeyScanLimit {
		return nil, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitExceeded, MaxKeyScanLimit)
	}

	limit := int(req.Limit)

	if req.Limit == 0 {
		limit = MaxKeyScanLimit
	}

	d.mutex.RLock()
	defer d.mutex.RUnlock()

	currTxID, _ := d.st.Alh()

	if req.SinceTx > currTxID {
		return nil, ErrIllegalArguments
	}

	waitUntilTx := req.SinceTx
	if waitUntilTx == 0 {
		waitUntilTx = currTxID
	}

	if !req.NoWait {
		err := d.st.WaitForIndexingUpto(waitUntilTx, nil)
		if err != nil {

Review comment (suggestion):
```suggestion
		return nil, fmt.Errorf("%w: given limit (%d) is larger than the maximum allowed one (%d)", ErrMaxKeyScanLimitExceeded, req.Limit, MaxKeyScanLimit)
```

Code after:
	if err != nil {
		return nil, err
	}

	var hdr *store.TxHeader

	if req.NoWait {
		hdr, err = tx.AsyncCommit()
	} else {
		hdr, err = tx.Commit()
	}
	if err != nil {
		return nil, err
	}

	return schema.TxHeaderToProto(hdr), nil
}

// ZScan ...
func (d *db) ZScan(req *schema.ZScanRequest) (*schema.ZEntries, error) {
	if req == nil || len(req.Set) == 0 {
		return nil, store.ErrIllegalArguments
	}

	if req.Limit > uint64(d.maxResultSize) {
		return nil, fmt.Errorf("%w: the specified limit (%d) is larger than the maximum allowed one (%d)",
			ErrResultSizeLimitExceeded, req.Limit, d.maxResultSize)
	}

	limit := int(req.Limit)

	if req.Limit == 0 {
		limit = d.maxResultSize
	}

	d.mutex.RLock()
	defer d.mutex.RUnlock()

	currTxID, _ := d.st.Alh()

	if req.SinceTx > currTxID {
		return nil, ErrIllegalArguments
	}

	waitUntilTx := req.SinceTx
	if waitUntilTx == 0 {
		waitUntilTx = currTxID
	}

	if !req.NoWait {
		err := d.st.WaitForIndexingUpto(waitUntilTx, nil)
Repository: codenotary/immudb
File: pkg/database/sorted_set.go (Go)

Code before:
		key := make([]byte, len(zKey)-keyOff-txIDLen)
		copy(key, zKey[keyOff:])

		atTx := binary.BigEndian.Uint64(zKey[keyOff+len(key):])

		e, err := d.getAtTx(key, atTx, 1, snap, tx, 0)
		if err == store.ErrKeyNotFound {
			// ignore deleted ones (referenced key may have been deleted)
			continue
		}
		if err != nil {
			return nil, err
		}

		zentry := &schema.ZEntry{
			Set:   req.Set,
			Key:   key[1:],
			Entry: e,
			Score: score,
			AtTx:  atTx,
		}

		entries.Entries = append(entries.Entries, zentry)

		if l == MaxKeyScanLimit {
			return entries, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
		}
	}

	return entries, nil
}

//VerifiableZAdd ...
func (d *db) VerifiableZAdd(req *schema.VerifiableZAddRequest) (*schema.VerifiableTx, error) {
	if req == nil {
		return nil, store.ErrIllegalArguments
	}

	lastTxID, _ := d.st.Alh()
	if lastTxID < req.ProveSinceTx {
		return nil, store.ErrIllegalArguments
	}

	txMetatadata, err := d.ZAdd(req.ZAddRequest)
	if err != nil {
		return nil, err
	}

	lastTx := d.st.NewTxHolder()

	err = d.st.ReadTx(uint64(txMetatadata.Id), lastTx)

Review comment (suggestion):
```suggestion
			return entries, fmt.Errorf("%w: found more than %d entries (the maximum limit), please use the limit, seekKey, seekScore and seekAtTx arguments to paginate over large results", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
```

Code after:
		keyOff := scoreOff + scoreLen + keyLenLen
		key := make([]byte, len(zKey)-keyOff-txIDLen)
		copy(key, zKey[keyOff:])

		atTx := binary.BigEndian.Uint64(zKey[keyOff+len(key):])

		e, err := d.getAtTx(key, atTx, 1, snap, tx, 0)
		if err == store.ErrKeyNotFound {
			// ignore deleted ones (referenced key may have been deleted)
			continue
		}
		if err != nil {
			return nil, err
		}

		zentry := &schema.ZEntry{
			Set:   req.Set,
			Key:   key[1:],
			Entry: e,
			Score: score,
			AtTx:  atTx,
		}

		entries.Entries = append(entries.Entries, zentry)

		if l == d.maxResultSize {
			return entries, fmt.Errorf("%w: found at least %d entries (the maximum limit). "+
				"Pagination over large results can be achieved by using the limit, seekKey, seekScore and seekAtTx arguments",
				ErrResultSizeLimitReached, d.maxResultSize)
		}
	}

	return entries, nil
}

//VerifiableZAdd ...
func (d *db) VerifiableZAdd(req *schema.VerifiableZAddRequest) (*schema.VerifiableTx, error) {
	if req == nil {
		return nil, store.ErrIllegalArguments
	}

	lastTxID, _ := d.st.Alh()
	if lastTxID < req.ProveSinceTx {
		return nil, store.ErrIllegalArguments
	}

	txMetatadata, err := d.ZAdd(req.ZAddRequest)
	if err != nil {
		return nil, err
	}
Repository: codenotary/immudb
File: pkg/database/sql.go (Go)

Code before:
		if err != nil {
			return nil, err
		}

		rrow := &schema.Row{
			Columns: make([]string, len(res.Columns)),
			Values:  make([]*schema.SQLValue, len(res.Columns)),
		}

		for i := range colDescriptors {
			rrow.Columns[i] = cols[i].Name

			v := row.ValuesByPosition[i]

			_, isNull := v.(*sql.NullValue)
			if isNull {
				rrow.Values[i] = &schema.SQLValue{Value: &schema.SQLValue_Null{}}
			} else {
				rrow.Values[i] = typedValueToRowValue(v)
			}
		}

		res.Rows = append(res.Rows, rrow)

		if l == MaxKeyScanLimit {
			return res, fmt.Errorf("%w: %d is the limit", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
		}
	}

	return res, nil
}

func (d *db) SQLQueryRowReader(stmt sql.DataSource, params map[string]interface{}, tx *sql.SQLTx) (sql.RowReader, error) {
	if stmt == nil {
		return nil, ErrIllegalArguments
	}

	d.mutex.RLock()
	defer d.mutex.RUnlock()

	if d.isReplica() {
		err := d.reloadSQLCatalog()
		if err != nil {
			return nil, err
		}
	}

	return d.sqlEngine.QueryPreparedStmt(stmt, params, tx)
}

func (d *db) InferParameters(sql string, tx *sql.SQLTx) (map[string]sql.SQLValueType, error) {

Review comment (suggestion):
```suggestion
			return res, fmt.Errorf("%w: found more than %d rows (the maximum limit), please constrain the query with LIMIT clause", ErrMaxKeyScanLimitReached, MaxKeyScanLimit)
```

Code after:
		if err != nil {
			return nil, err
		}

		rrow := &schema.Row{
			Columns: make([]string, len(res.Columns)),
			Values:  make([]*schema.SQLValue, len(res.Columns)),
		}

		for i := range colDescriptors {
			rrow.Columns[i] = cols[i].Name

			v := row.ValuesByPosition[i]

			_, isNull := v.(*sql.NullValue)
			if isNull {
				rrow.Values[i] = &schema.SQLValue{Value: &schema.SQLValue_Null{}}
			} else {
				rrow.Values[i] = typedValueToRowValue(v)
			}
		}

		res.Rows = append(res.Rows, rrow)

		if l == d.maxResultSize {
			return res, fmt.Errorf("%w: found at least %d rows (the maximum limit). "+
				"Query constraints can be applied using the LIMIT clause",
				ErrResultSizeLimitReached, d.maxResultSize)
		}
	}

	return res, nil
}

func (d *db) SQLQueryRowReader(stmt sql.DataSource, params map[string]interface{}, tx *sql.SQLTx) (sql.RowReader, error) {
	if stmt == nil {
		return nil, ErrIllegalArguments
	}

	d.mutex.RLock()
	defer d.mutex.RUnlock()

	if d.isReplica() {
		err := d.reloadSQLCatalog()
		if err != nil {
			return nil, err
		}
	}

	return d.sqlEngine.QueryPreparedStmt(stmt, params, tx)
}
Repository: codenotary/immudb
File: pkg/client/session.go (Go)

Code before:
	c.Options.DialOptions = c.SetupDialOptions(c.Options)

	if c.Options.ServerSigningPubKey != "" {
		pk, e := signer.ParsePublicKeyFile(c.Options.ServerSigningPubKey)
		if e != nil {
			return e
		}
		c.WithServerSigningPubKey(pk)
	}

	if c.Options.StreamChunkSize < stream.MinChunkSize {
		return errors.New(stream.ErrChunkTooSmall).WithCode(errors.CodInvalidParameterValue)
	}

	if c.clientConn, err = grpc.Dial(c.Options.Bind(), c.Options.DialOptions...); err != nil {
		return err
	}

	c.ServiceClient = schema.NewImmuServiceClient(c.clientConn)
	defer func(){
		if err != nil {
			_, _ = c.ServiceClient.CloseSession(ctx, new(empty.Empty))
		}
	}()

	resp, err := c.ServiceClient.OpenSession(ctx, &schema.OpenSessionRequest{
		Username:     user,
		Password:     pass,
		DatabaseName: database,
	})
	if err != nil {
		return errors.FromError(err)
	}

	c.SessionID = resp.GetSessionID()
	defer func(){
		if err != nil {
			c.SessionID = ""
		}
	}()

	c.HeartBeater = heartbeater.NewHeartBeater(resp.GetSessionID(), c.ServiceClient, c.Options.HeartBeatFrequency)
	defer func(){
		if err != nil {
			c.HeartBeater.Stop()
		}
	}()
	c.HeartBeater.KeepAlive(ctx)

	stateProvider := state.NewStateProvider(c.ServiceClient)


Review comment (suggestion):
probably it'd be better to set a local variable and set the attribute in the client when all steps succeeded

Code after:
	if c.Options.StreamChunkSize < stream.MinChunkSize {
		return errors.New(stream.ErrChunkTooSmall).WithCode(errors.CodInvalidParameterValue)
	}

	dialOptions := c.SetupDialOptions(c.Options)

	clientConn, err := grpc.Dial(c.Options.Bind(), dialOptions...)
	if err != nil {
		return err
	}
	defer func(){
		if err != nil {
			_ = clientConn.Close()
		}
	}()

	serviceClient := schema.NewImmuServiceClient(clientConn)
	resp, err := serviceClient.OpenSession(ctx, &schema.OpenSessionRequest{
		Username:     user,
		Password:     pass,
		DatabaseName: database,
	})
	if err != nil {
		return errors.FromError(err)
	}
	defer func(){
		if err != nil {
			_, _ = serviceClient.CloseSession(ctx, new(empty.Empty))
		}
	}()

	stateProvider := state.NewStateProvider(serviceClient)

	stateService, err := state.NewStateServiceWithUUID(cache.NewFileCache(c.Options.Dir), c.Logger, stateProvider, resp.GetServerUUID())
	if err != nil {
		return errors.FromError(fmt.Errorf("unable to create state service: %v", err))
	}

	c.clientConn = clientConn
	c.ServiceClient = serviceClient
	c.Options.DialOptions = dialOptions
	c.SessionID = resp.GetSessionID()

	c.HeartBeater = heartbeater.NewHeartBeater(c.SessionID, c.ServiceClient, c.Options.HeartBeatFrequency)
	c.HeartBeater.KeepAlive(ctx)

	c.WithStateService(stateService)

	c.Options.CurrentDatabase = database

	return nil