Adds our_diff_type and their_diff_type to dolt_conflicts_table_name (#3748)

* add our_diff_type and their_diff_type to dolt_conflicts_table_name

* pr comments

* [ga-format-pr] Run go/utils/repofmt/format_repo.sh and go/Godeps/update.sh

Co-authored-by: druvv <druvv@users.noreply.github.com>
This commit is contained in:
Dhruv Sringari
2022-07-05 12:11:23 -07:00
committed by GitHub
parent 3b96cc3570
commit 1c0e7679d7
7 changed files with 124 additions and 8 deletions
@@ -167,6 +167,11 @@ func TestSystemTableTags(t *testing.T) {
assert.Equal(t, doltSchemasMin+3, schema.DoltSchemasFragmentTag)
assert.Equal(t, doltSchemasMin+4, schema.DoltSchemasExtraTag)
})
t.Run("dolt_conflicts_ tags", func(t *testing.T) {
doltConflictsMin := sysTableMin + uint64(7000)
assert.Equal(t, doltConflictsMin+0, schema.DoltConflictsOurDiffTypeTag)
assert.Equal(t, doltConflictsMin+1, schema.DoltConflictsTheirDiffTypeTag)
})
}
func TestEmptyInMemoryRepoCreation(t *testing.T) {
+34 -2
View File
@@ -39,11 +39,18 @@ const (
baseStr = "base"
)
const (
ConflictDiffTypeAdded = "added"
ConflictDiffTypeModified = "modified"
ConflictDiffTypeRemoved = "removed"
)
// ConflictReader is a class providing a NextConflict function which can be used in a pipeline as a pipeline.SourceFunc,
// or it can be used to read each conflict
type ConflictReader struct {
confItr types.MapIterator
joiner *rowconv.Joiner
sch schema.Schema
nbf *types.NomsBinFormat
}
@@ -76,6 +83,16 @@ func NewConflictReader(ctx context.Context, tbl *doltdb.Table) (*ConflictReader,
return nil, err
}
readerSch := joiner.GetSchema()
readerSch, err = readerSch.AddColumn(schema.NewColumn("our_diff_type", schema.DoltConflictsOurDiffTypeTag, types.StringKind, false), nil)
if err != nil {
return nil, err
}
readerSch, err = readerSch.AddColumn(schema.NewColumn("their_diff_type", schema.DoltConflictsTheirDiffTypeTag, types.StringKind, false), nil)
if err != nil {
return nil, err
}
_, confIdx, err := tbl.GetConflicts(ctx)
if err != nil {
return nil, err
@@ -91,7 +108,7 @@ func NewConflictReader(ctx context.Context, tbl *doltdb.Table) (*ConflictReader,
return nil, err
}
return &ConflictReader{confItr, joiner, tbl.Format()}, nil
return &ConflictReader{confItr: confItr, joiner: joiner, sch: readerSch, nbf: tbl.Format()}, nil
}
func tagMappingConverter(ctx context.Context, vrw types.ValueReadWriter, src, dest schema.Schema) (*rowconv.RowConverter, error) {
@@ -106,7 +123,7 @@ func tagMappingConverter(ctx context.Context, vrw types.ValueReadWriter, src, de
// GetSchema gets the schema of the rows that this reader will return
func (cr *ConflictReader) GetSchema() schema.Schema {
return cr.joiner.GetSchema()
return cr.sch
}
// GetJoiner returns the joiner used to join a row with its base, and merge versions
@@ -162,6 +179,11 @@ func (cr *ConflictReader) NextConflict(ctx context.Context) (row.Row, pipeline.I
joinedRow, err := cr.joiner.Join(namedRows)
ourDiffType := getDiffType(conflict.Base, conflict.Value)
theirDiffType := getDiffType(conflict.Base, conflict.MergeValue)
joinedRow, err = joinedRow.SetColVal(schema.DoltConflictsOurDiffTypeTag, types.String(ourDiffType), cr.sch)
joinedRow, err = joinedRow.SetColVal(schema.DoltConflictsTheirDiffTypeTag, types.String(theirDiffType), cr.sch)
if err != nil {
return nil, pipeline.NoProps, err
}
@@ -169,6 +191,16 @@ func (cr *ConflictReader) NextConflict(ctx context.Context) (row.Row, pipeline.I
return joinedRow, pipeline.NoProps, nil
}
func getDiffType(base types.Value, other types.Value) string {
if types.IsNull(base) {
return ConflictDiffTypeAdded
} else if types.IsNull(other) {
return ConflictDiffTypeRemoved
}
return ConflictDiffTypeModified
}
// GetKeyForConflicts returns the pk for a conflict row
func (cr *ConflictReader) GetKeyForConflict(ctx context.Context, r row.Row) (types.Value, error) {
rows, err := cr.joiner.Split(r)
+4 -1
View File
@@ -137,7 +137,10 @@ func (j *Joiner) Split(r row.Row) (map[string]row.Row, error) {
}
_, err := r.IterCols(func(tag uint64, val types.Value) (stop bool, err error) {
schemaNameAndTag := j.revTagMap[tag]
schemaNameAndTag, ok := j.revTagMap[tag]
if !ok {
return false, nil
}
colVals[schemaNameAndTag.str][schemaNameAndTag.u64] = val
return false, nil
@@ -99,3 +99,9 @@ const (
DoltConstraintViolationsTypeTag = 0
DoltConstraintViolationsInfoTag = math.MaxUint64
)
// Tags for the dolt_conflicts_table_name table
const (
DoltConflictsOurDiffTypeTag = iota + SystemTableReservedMin + uint64(7000)
DoltConflictsTheirDiffTypeTag
)
@@ -22,6 +22,7 @@ import (
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb/durable"
"github.com/dolthub/dolt/go/libraries/doltcore/merge"
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/index"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil"
@@ -122,6 +123,7 @@ type prollyConflictRowIter struct {
var _ sql.RowIter = &prollyConflictRowIter{}
// base_cols, our_cols, our_diff_type, their_cols, their_diff_type
func newProllyConflictRowIter(ctx *sql.Context, ct ProllyConflictsTable) (*prollyConflictRowIter, error) {
idx, err := ct.tbl.GetRowData(ctx)
if err != nil {
@@ -145,12 +147,12 @@ func newProllyConflictRowIter(ctx *sql.Context, ct ProllyConflictsTable) (*proll
var o, t, n int
if !keyless {
o = b + kd.Count() + baseVD.Count()
t = o + kd.Count() + oursVD.Count()
n = t + kd.Count() + theirsVD.Count()
t = o + kd.Count() + oursVD.Count() + 1
n = t + kd.Count() + theirsVD.Count() + 1
} else {
o = b + baseVD.Count() - 1
t = o + oursVD.Count() - 1
n = t + theirsVD.Count() - 1
t = o + oursVD.Count()
n = t + theirsVD.Count()
}
return &prollyConflictRowIter{
@@ -230,6 +232,7 @@ func (itr *prollyConflictRowIter) putConflictRowVals(ctx *sql.Context, c conf, r
r[itr.o+itr.kd.Count()+i] = f
}
}
r[itr.o+itr.kd.Count()+itr.oursVD.Count()] = getDiffType(c.bV, c.oV)
if c.tV != nil {
for i := 0; i < itr.theirsVD.Count(); i++ {
@@ -240,10 +243,22 @@ func (itr *prollyConflictRowIter) putConflictRowVals(ctx *sql.Context, c conf, r
r[itr.t+itr.kd.Count()+i] = f
}
}
r[itr.t+itr.kd.Count()+itr.theirsVD.Count()] = getDiffType(c.bV, c.tV)
return nil
}
func getDiffType(base val.Tuple, other val.Tuple) string {
if base == nil {
return merge.ConflictDiffTypeAdded
} else if other == nil {
return merge.ConflictDiffTypeRemoved
}
// There has to be some edit, otherwise it wouldn't be a conflict...
return merge.ConflictDiffTypeModified
}
func (itr *prollyConflictRowIter) putKeylessConflictRowVals(ctx *sql.Context, c conf, r sql.Row) error {
if c.bV != nil {
for i := 0; i < itr.baseVD.Count()-1; i++ {
@@ -264,6 +279,7 @@ func (itr *prollyConflictRowIter) putKeylessConflictRowVals(ctx *sql.Context, c
r[itr.o+i] = f
}
}
r[itr.o+itr.oursVD.Count()-1] = getDiffType(c.bV, c.oV)
if c.tV != nil {
for i := 0; i < itr.theirsVD.Count()-1; i++ {
@@ -274,6 +290,7 @@ func (itr *prollyConflictRowIter) putKeylessConflictRowVals(ctx *sql.Context, c
r[itr.t+i] = f
}
}
r[itr.t+itr.theirsVD.Count()-1] = getDiffType(c.bV, c.tV)
return nil
}
@@ -478,7 +495,7 @@ func (cd *prollyConflictDeleter) Close(ctx *sql.Context) error {
}
func CalculateConflictSchema(base, ours, theirs schema.Schema) (schema.Schema, error) {
cols := make([]schema.Column, 1+ours.GetAllCols().Size()+theirs.GetAllCols().Size()+base.GetAllCols().Size())
cols := make([]schema.Column, 3+ours.GetAllCols().Size()+theirs.GetAllCols().Size()+base.GetAllCols().Size())
// the commit hash or working set hash of the right side during merge
cols[0] = schema.NewColumn("from_root_ish", 0, types.StringKind, false)
@@ -517,10 +534,13 @@ func CalculateConflictSchema(base, ours, theirs schema.Schema) (schema.Schema, e
if err != nil {
return nil, err
}
cols[i] = schema.NewColumn("our_diff_type", uint64(i), types.StringKind, false)
i++
err = putWithPrefix("their_", theirs)
if err != nil {
return nil, err
}
cols[i] = schema.NewColumn("their_diff_type", uint64(i), types.StringKind, false)
return schema.UnkeyedSchemaFromCols(schema.NewColCollection(cols...)), nil
}
@@ -692,6 +692,12 @@ func TestDoltMerge(t *testing.T) {
}
}
func TestDoltConflictsTableNameTable(t *testing.T) {
for _, script := range DoltConflictDiffTypeScripts {
enginetest.TestScript(t, newDoltHarness(t), script)
}
}
// tests new format behavior for keyless merges that create CVs and conflicts
func TestKeylessDoltMergeCVsAndConflicts(t *testing.T) {
if !types.IsFormat_DOLT_1(types.Format_Default) {
@@ -1624,6 +1624,50 @@ var KeylessMergeCVsAndConflictsScripts = []queries.ScriptTest{
},
}
var DoltConflictDiffTypeScripts = []queries.ScriptTest{
{
Name: "conflict diff types",
SetUpScript: []string{
"SET dolt_allow_commit_conflicts = on;",
"CREATE table t (pk int PRIMARY KEY, col1 int);",
"INSERT INTO t VALUES (1, 1);",
"INSERT INTO t VALUES (2, 2);",
"INSERT INTO t VALUES (3, 3);",
"CALL DOLT_COMMIT('-am', 'create table with row');",
"CALL DOLT_CHECKOUT('-b', 'other');",
"UPDATE t set col1 = 3 where pk = 1;",
"UPDATE t set col1 = 0 where pk = 2;",
"DELETE FROM t where pk = 3;",
"INSERT INTO t VALUES (4, -4);",
"CALL DOLT_COMMIT('-am', 'right edit');",
"CALL DOLT_CHECKOUT('main');",
"UPDATE t set col1 = 2 where pk = 1;",
"DELETE FROM t where pk = 2;",
"UPDATE t set col1 = 0 where pk = 3;",
"INSERT INTO t VALUES (4, 4);",
"CALL DOLT_COMMIT('-am', 'left edit');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "CALL DOLT_MERGE('other');",
Expected: []sql.Row{{0, 1}},
},
{
Query: "SELECT base_pk, base_col1, our_pk, our_col1, our_diff_type, their_pk, their_col1, their_diff_type" +
" from dolt_conflicts_t ORDER BY COALESCE(base_pk, our_pk, their_pk) ASC;",
Expected: []sql.Row{
{1, 1, 1, 2, "modified", 1, 3, "modified"},
{2, 2, nil, nil, "removed", 2, 0, "modified"},
{3, 3, 3, 0, "modified", nil, nil, "removed"},
{nil, nil, 4, 4, "added", 4, -4, "added"},
},
},
},
},
}
// MergeArtifactsScripts tests new format merge behavior where
// existing violations and conflicts are merged together.
var MergeArtifactsScripts = []queries.ScriptTest{