func (pke *pkTableEditAccumulator) getPks(r sql.Row) sql.Row {
	pkIdxs := pke.pkColumnIndexes()
	ret := sql.Row{}
	for _, idx := range pkIdxs {
		ret = append(ret, r[idx])
	}
	return ret
}
getPks returns a sql.Row of the primary partitionKeys a row in relation with the initialized table.
package memory
import (
	"fmt"
	"github.com/dolthub/go-mysql-server/sql"
)
type tableEditor struct {
	table             *Table
	initialAutoIncVal interface{}
	initialPartitions map[string][]sql.Row
	ea                tableEditAccumulator
	initialInsert     int
}
var _ sql.RowReplacer = (*tableEditor)(nil)
var _ sql.RowUpdater = (*tableEditor)(nil)
var _ sql.RowInserter = (*tableEditor)(nil)
var _ sql.RowDeleter = (*tableEditor)(nil)
func (t *tableEditor) Close(ctx *sql.Context) error {
	return t.ea.ApplyEdits(ctx)
}
func (t *tableEditor) StatementBegin(ctx *sql.Context) {
	t.initialInsert = t.table.insertPartIdx
	t.initialAutoIncVal = t.table.autoIncVal
	t.initialPartitions = make(map[string][]sql.Row)
	for partStr, rowSlice := range t.table.partitions {
		newRowSlice := make([]sql.Row, len(rowSlice))
		for i, row := range rowSlice {
			newRowSlice[i] = row.Copy()
		}
		t.initialPartitions[partStr] = newRowSlice
	}
}
func (t *tableEditor) DiscardChanges(ctx *sql.Context, errorEncountered error) error {
	t.table.insertPartIdx = t.initialInsert
	t.table.autoIncVal = t.initialAutoIncVal
	t.table.partitions = t.initialPartitions
	t.ea.Clear()
	return nil
}
func (t *tableEditor) StatementComplete(ctx *sql.Context) error {
	return nil
}
func (t *tableEditor) Insert(ctx *sql.Context, row sql.Row) error {
	if err := checkRow(t.table.schema, row); err != nil {
		return err
	}
	partitionRow, added, err := t.ea.Get(row)
	if err != nil {
		return err
	}
	if added {
		pkColIdxes := t.pkColumnIndexes()
		vals := make([]interface{}, len(pkColIdxes))
		for _, i := range pkColIdxes {
			vals[i] = row[pkColIdxes[i]]
		}
		return sql.NewUniqueKeyErr(fmt.Sprint(vals), true, partitionRow)
	}
	err = t.ea.Insert(row)
	if err != nil {
		return err
	}
	idx := t.table.autoColIdx
	if idx >= 0 {
		autoCol := t.table.schema[idx]
		cmp, err := autoCol.Type.Compare(row[idx], t.table.autoIncVal)
		if err != nil {
			return err
		}
		if cmp > 0 {
			t.table.autoIncVal = row[idx]
		}
		t.table.autoIncVal = increment(t.table.autoIncVal)
	}
	return nil
}
func (t *tableEditor) Delete(ctx *sql.Context, row sql.Row) error {
	if err := checkRow(t.table.schema, row); err != nil {
		return err
	}
	err := t.ea.Delete(row)
	if err != nil {
		return err
	}
	return nil
}
func (t *tableEditor) Update(ctx *sql.Context, oldRow sql.Row, newRow sql.Row) error {
	if err := checkRow(t.table.schema, oldRow); err != nil {
		return err
	}
	if err := checkRow(t.table.schema, newRow); err != nil {
		return err
	}
	err := t.ea.Delete(oldRow)
	if err != nil {
		return err
	}
	if t.pkColsDiffer(oldRow, newRow) {
		partitionRow, added, err := t.ea.Get(newRow)
		if err != nil {
			return err
		}
		if added {
			pkColIdxes := t.pkColumnIndexes()
			vals := make([]interface{}, len(pkColIdxes))
			for _, i := range pkColIdxes {
				vals[i] = newRow[pkColIdxes[i]]
			}
			return sql.NewUniqueKeyErr(fmt.Sprint(vals), true, partitionRow)
		}
	}
	err = t.ea.Insert(newRow)
	if err != nil {
		return err
	}
	return nil
}
func (t *tableEditor) SetAutoIncrementValue(ctx *sql.Context, val interface{}) error {
	t.table.autoIncVal = val
	return nil
}
func (t *tableEditor) pkColumnIndexes() []int {
	var pkColIdxes []int
	for _, column := range t.table.schema {
		if column.PrimaryKey {
			idx, _ := t.table.getField(column.Name)
			pkColIdxes = append(pkColIdxes, idx)
		}
	}
	return pkColIdxes
}
func (t *tableEditor) pkColsDiffer(row, row2 sql.Row) bool {
	pkColIdxes := t.pkColumnIndexes()
	return !columnsMatch(pkColIdxes, row, row2)
}
func columnsMatch(colIndexes []int, row sql.Row, row2 sql.Row) bool {
	for _, i := range colIndexes {
		if row[i] != row2[i] {
			return false
		}
	}
	return true
}
type tableEditAccumulator interface {
	Insert(value sql.Row) error
	Delete(value sql.Row) error
	Get(value sql.Row) (sql.Row, bool, error)
	ApplyEdits(ctx *sql.Context) error
	Clear()
}
func NewTableEditAccumulator(t *Table) tableEditAccumulator {
	if sql.IsKeyless(t.schema) {
		return &keylessTableEditAccumulator{
			table:   t,
			adds:    make([]sql.Row, 0),
			deletes: make([]sql.Row, 0),
		}
	}
	return &pkTableEditAccumulator{
		table:   t,
		adds:    make(map[uint64]sql.Row),
		deletes: make(map[uint64]sql.Row),
	}
}
type pkTableEditAccumulator struct {
	table   *Table
	adds    map[uint64]sql.Row
	deletes map[uint64]sql.Row
}
var _ tableEditAccumulator = (*pkTableEditAccumulator)(nil)
func (pke *pkTableEditAccumulator) Insert(value sql.Row) error {
	pks := pke.getPks(value)
	pkHash, err := sql.HashOf(pks)
	if err != nil {
		return err
	}
	delete(pke.deletes, pkHash)
	pke.adds[pkHash] = value
	return nil
}
func (pke *pkTableEditAccumulator) Delete(value sql.Row) error {
	pks := pke.getPks(value)
	pkHash, err := sql.HashOf(pks)
	if err != nil {
		return err
	}
	delete(pke.adds, pkHash)
	pke.deletes[pkHash] = value
	return nil
}
func (pke *pkTableEditAccumulator) Get(value sql.Row) (sql.Row, bool, error) {
	pks := pke.getPks(value)
	pkHash, err := sql.HashOf(pks)
	if err != nil {
		return nil, false, err
	}
	r, exists := pke.adds[pkHash]
	if exists {
		return r, true, nil
	}
	r, exists = pke.deletes[pkHash]
	if exists {
		return r, false, nil
	}
	pkColIdxes := pke.pkColumnIndexes()
	for _, partition := range pke.table.partitions {
		for _, partitionRow := range partition {
			if columnsMatch(pkColIdxes, partitionRow, value) {
				return partitionRow, true, nil
			}
		}
	}
	return nil, false, nil
}
func (pke *pkTableEditAccumulator) ApplyEdits(ctx *sql.Context) error {
	for _, val := range pke.deletes {
		err := pke.deleteHelper(ctx, pke.table, val)
		if err != nil {
			return err
		}
	}
	for _, val := range pke.adds {
		err := pke.insertHelper(ctx, pke.table, val)
		if err != nil {
			return err
		}
	}
	return nil
}
func (pke *pkTableEditAccumulator) Clear() {
	pke.adds = make(map[uint64]sql.Row)
	pke.deletes = make(map[uint64]sql.Row)
}
func (pke *pkTableEditAccumulator) pkColumnIndexes() []int {
	var pkColIdxes []int
	for _, column := range pke.table.schema {
		if column.PrimaryKey {
			idx, _ := pke.table.getField(column.Name)
			pkColIdxes = append(pkColIdxes, idx)
		}
	}
	return pkColIdxes
}