From c94a1fabe32afad619e693fb0654df4f7ffdbbfc Mon Sep 17 00:00:00 2001 From: Daylon Wilkins Date: Thu, 7 Aug 2025 06:49:05 -0700 Subject: [PATCH] Fixed merge issues --- core/conflicts/collection.go | 11 ++++ core/conflicts/collection_funcs.go | 7 +++ core/conflicts/root_object.go | 16 ++++-- core/conflicts/serialization.go | 57 ++++++++++++++------- core/extensions/collection_funcs.go | 14 +++++ core/functions/collection_funcs.go | 16 ++++++ core/rootobject/collection.go | 56 ++++++++++++++++++-- core/rootobject/init.go | 1 + core/rootobject/objinterface/interfaces.go | 4 ++ core/rootobject/objinterface/root_object.go | 2 + core/sequences/collection_funcs.go | 27 ++++++++++ core/triggers/collection_funcs.go | 16 ++++++ core/typecollection/collection_funcs.go | 27 ++++++++++ go.mod | 4 +- go.sum | 8 +-- testing/go/conflicts_root_object_test.go | 20 +++----- 16 files changed, 240 insertions(+), 46 deletions(-) diff --git a/core/conflicts/collection.go b/core/conflicts/collection.go index f5ebbe0003..471331eda2 100644 --- a/core/conflicts/collection.go +++ b/core/conflicts/collection.go @@ -250,6 +250,11 @@ func (conflict Conflict) FieldType(ctx context.Context, name string) *pgtypes.Do return GetFieldType(ctx, conflict.RootObjectID, name) } +// GetContainedRootObjectID implements the interface objinterface.RootObject. +func (conflict Conflict) GetContainedRootObjectID() objinterface.RootObjectID { + return conflict.RootObjectID +} + // GetID implements the interface objinterface.RootObject. func (conflict Conflict) GetID() id.Id { return conflict.ID @@ -383,6 +388,12 @@ var GetFieldType = func(ctx context.Context, rootObjID objinterface.RootObjectID panic("GetFieldType was never initialized") } +// ResolveNameExternal handles name resolution across all collection types, and is declared in a different package. It +// is assigned here by an Init function to get around import cycles. +var ResolveNameExternal = func(ctx context.Context, name doltdb.TableName, rootObjects []objinterface.RootObject) (doltdb.TableName, id.Id, error) { + panic("ResolveNameExternal was never initialized") +} + // UpdateField handles updating fields in a root object, and is declared in a different package. It is assigned here by // an Init function to get around import cycles. var UpdateField = func(ctx context.Context, rootObjID objinterface.RootObjectID, rootObject objinterface.RootObject, fieldName string, newValue any) (objinterface.RootObject, error) { diff --git a/core/conflicts/collection_funcs.go b/core/conflicts/collection_funcs.go index 51fc697b74..21b41ee7b4 100644 --- a/core/conflicts/collection_funcs.go +++ b/core/conflicts/collection_funcs.go @@ -23,6 +23,7 @@ import ( "github.com/dolthub/dolt/go/store/hash" "github.com/dolthub/dolt/go/store/prolly" + "github.com/dolthub/doltgresql/core/id" "github.com/dolthub/doltgresql/core/rootobject/objinterface" "github.com/dolthub/doltgresql/flatbuffers/gen/serial" ) @@ -95,6 +96,12 @@ func LoadConflicts(ctx context.Context, root objinterface.RootValue) (*Collectio return NewCollection(ctx, m, root.NodeStore()) } +// ResolveNameFromObjects implements the interface objinterface.Collection. +func (*Collection) ResolveNameFromObjects(ctx context.Context, name doltdb.TableName, rootObjects []objinterface.RootObject) (doltdb.TableName, id.Id, error) { + // Conflicts make use of this interface function, so we must return nil to prevent infinite recursion + return doltdb.TableName{}, id.Null, nil +} + // Serializer implements the interface objinterface.Collection. func (*Collection) Serializer() objinterface.RootObjectSerializer { return storage diff --git a/core/conflicts/root_object.go b/core/conflicts/root_object.go index 0aa7984fb4..804fe1a7ce 100644 --- a/core/conflicts/root_object.go +++ b/core/conflicts/root_object.go @@ -96,10 +96,20 @@ func (pgc *Collection) RenameRootObject(ctx context.Context, oldName id.Id, newN // ResolveName implements the interface objinterface.Collection. func (pgc *Collection) ResolveName(ctx context.Context, name doltdb.TableName) (doltdb.TableName, id.Id, error) { - if resolvedId, ok := pgc.nameCache[name]; ok { - return name, resolvedId, nil + if len(pgc.idCache) == 0 { + return doltdb.TableName{}, id.Null, nil + } + objs := make([]objinterface.RootObject, 0, len(pgc.idCache)) + for _, conflict := range pgc.accessCache { + if conflict.Ours != nil { + objs = append(objs, conflict.Ours) + } else if conflict.Theirs != nil { + objs = append(objs, conflict.Theirs) + } else if conflict.Ancestor != nil { + objs = append(objs, conflict.Ancestor) + } } - return doltdb.TableName{}, id.Null, nil + return ResolveNameExternal(ctx, name, objs) } // TableNameToID implements the interface objinterface.Collection. diff --git a/core/conflicts/serialization.go b/core/conflicts/serialization.go index 21a7cbc415..77d0ba8690 100644 --- a/core/conflicts/serialization.go +++ b/core/conflicts/serialization.go @@ -24,7 +24,7 @@ import ( ) // Serialize returns the Conflict as a byte slice. If the Conflict is invalid, then this returns a nil slice. -func (conflict Conflict) Serialize(ctx context.Context) ([]byte, error) { +func (conflict Conflict) Serialize(ctx context.Context) (_ []byte, err error) { if !conflict.ID.IsValid() { return nil, nil } @@ -33,22 +33,32 @@ func (conflict Conflict) Serialize(ctx context.Context) ([]byte, error) { writer := utils.NewWriter(512) writer.VariableUint(0) // Version // Serialize "ours", "theirs", and "ancestor" - ours, err := conflict.Ours.Serialize(ctx) - if err != nil { - return nil, err + var ours, theirs, ancestor []byte + if conflict.Ours != nil { + ours, err = conflict.Ours.Serialize(ctx) + if err != nil { + return nil, err + } } - theirs, err := conflict.Theirs.Serialize(ctx) - if err != nil { - return nil, err + if conflict.Theirs != nil { + theirs, err = conflict.Theirs.Serialize(ctx) + if err != nil { + return nil, err + } } - ancestor, err := conflict.Ancestor.Serialize(ctx) - if err != nil { - return nil, err + if conflict.Ancestor != nil { + ancestor, err = conflict.Ancestor.Serialize(ctx) + if err != nil { + return nil, err + } } // Write the conflict data writer.Id(conflict.ID) writer.String(conflict.FromHash) writer.Int64(int64(conflict.RootObjectID)) + writer.Bool(conflict.Ours != nil) + writer.Bool(conflict.Theirs != nil) + writer.Bool(conflict.Ancestor != nil) writer.ByteSlice(ours) writer.ByteSlice(theirs) writer.ByteSlice(ancestor) @@ -73,21 +83,30 @@ func DeserializeConflict(ctx context.Context, data []byte) (_ Conflict, err erro conflict.ID = reader.Id() conflict.FromHash = reader.String() conflict.RootObjectID = objinterface.RootObjectID(reader.Int64()) + hasOurs := reader.Bool() + hasTheirs := reader.Bool() + hasAncestor := reader.Bool() ours := reader.ByteSlice() theirs := reader.ByteSlice() ancestor := reader.ByteSlice() // Deserialize "ours", "theirs", and "ancestor" - conflict.Ours, err = DeserializeRootObject(ctx, conflict.RootObjectID, ours) - if err != nil { - return Conflict{}, err + if hasOurs { + conflict.Ours, err = DeserializeRootObject(ctx, conflict.RootObjectID, ours) + if err != nil { + return Conflict{}, err + } } - conflict.Theirs, err = DeserializeRootObject(ctx, conflict.RootObjectID, theirs) - if err != nil { - return Conflict{}, err + if hasTheirs { + conflict.Theirs, err = DeserializeRootObject(ctx, conflict.RootObjectID, theirs) + if err != nil { + return Conflict{}, err + } } - conflict.Ancestor, err = DeserializeRootObject(ctx, conflict.RootObjectID, ancestor) - if err != nil { - return Conflict{}, err + if hasAncestor { + conflict.Ancestor, err = DeserializeRootObject(ctx, conflict.RootObjectID, ancestor) + if err != nil { + return Conflict{}, err + } } if !reader.IsEmpty() { return Conflict{}, errors.Errorf("extra data found while deserializing a conflict") diff --git a/core/extensions/collection_funcs.go b/core/extensions/collection_funcs.go index 2a25d86ae0..734655f851 100644 --- a/core/extensions/collection_funcs.go +++ b/core/extensions/collection_funcs.go @@ -23,6 +23,7 @@ import ( "github.com/dolthub/dolt/go/store/hash" "github.com/dolthub/dolt/go/store/prolly" + "github.com/dolthub/doltgresql/core/id" "github.com/dolthub/doltgresql/core/rootobject/objinterface" "github.com/dolthub/doltgresql/flatbuffers/gen/serial" ) @@ -105,6 +106,19 @@ func LoadExtensions(ctx context.Context, root objinterface.RootValue) (*Collecti return NewCollection(ctx, m, root.NodeStore()) } +// ResolveNameFromObjects implements the interface objinterface.Collection. +func (*Collection) ResolveNameFromObjects(ctx context.Context, name doltdb.TableName, rootObjects []objinterface.RootObject) (doltdb.TableName, id.Id, error) { + tempCollection := Collection{ + accessCache: make(map[id.Extension]Extension), + } + for _, rootObject := range rootObjects { + if obj, ok := rootObject.(Extension); ok { + tempCollection.accessCache[obj.ExtName] = obj + } + } + return tempCollection.ResolveName(ctx, name) +} + // Serializer implements the interface objinterface.Collection. func (*Collection) Serializer() objinterface.RootObjectSerializer { return storage diff --git a/core/functions/collection_funcs.go b/core/functions/collection_funcs.go index 9bc91641e7..3f66b2e51a 100644 --- a/core/functions/collection_funcs.go +++ b/core/functions/collection_funcs.go @@ -23,6 +23,7 @@ import ( "github.com/dolthub/dolt/go/store/hash" "github.com/dolthub/dolt/go/store/prolly" + "github.com/dolthub/doltgresql/core/id" pgmerge "github.com/dolthub/doltgresql/core/merge" "github.com/dolthub/doltgresql/core/rootobject/objinterface" "github.com/dolthub/doltgresql/flatbuffers/gen/serial" @@ -95,6 +96,21 @@ func LoadFunctions(ctx context.Context, root objinterface.RootValue) (*Collectio return NewCollection(ctx, m, root.NodeStore()) } +// ResolveNameFromObjects implements the interface objinterface.Collection. +func (*Collection) ResolveNameFromObjects(ctx context.Context, name doltdb.TableName, rootObjects []objinterface.RootObject) (doltdb.TableName, id.Id, error) { + tempCollection := Collection{ + accessCache: make(map[id.Function]Function), + idCache: make([]id.Function, 0, len(rootObjects)), + } + for _, rootObject := range rootObjects { + if obj, ok := rootObject.(Function); ok { + tempCollection.accessCache[obj.ID] = obj + tempCollection.idCache = append(tempCollection.idCache, obj.ID) + } + } + return tempCollection.ResolveName(ctx, name) +} + // Serializer implements the interface objinterface.Collection. func (*Collection) Serializer() objinterface.RootObjectSerializer { return storage diff --git a/core/rootobject/collection.go b/core/rootobject/collection.go index bc14b9ec19..cf12888bd8 100644 --- a/core/rootobject/collection.go +++ b/core/rootobject/collection.go @@ -215,11 +215,14 @@ func GetRootObject(ctx context.Context, root objinterface.RootValue, tName doltd // GetRootObjectConflicts returns the conflict root object that matches the given name. func GetRootObjectConflicts(ctx context.Context, root objinterface.RootValue, tName doltdb.TableName) (conflicts.Conflict, bool, error) { - _, rawID, objID, err := ResolveName(ctx, root, tName) - if err != nil || objID == objinterface.RootObjectID_None { + coll, err := globalCollections[objinterface.RootObjectID_Conflicts].LoadCollection(ctx, root) + if err != nil { + return conflicts.Conflict{}, false, err + } + _, rawID, err := coll.ResolveName(ctx, tName) + if err != nil { return conflicts.Conflict{}, false, err } - coll, _ := globalCollections[objinterface.RootObjectID_Conflicts].LoadCollection(ctx, root) ro, ok, err := coll.GetRootObject(ctx, rawID) if err != nil || !ok { return conflicts.Conflict{}, false, err @@ -455,13 +458,13 @@ func PutRootObject(ctx context.Context, root objinterface.RootValue, tName doltd } } if merged == nil { - return RemoveRootObject(ctx, root, conflict.GetID(), conflict.GetRootObjectID()) + return RemoveRootObjectIfExists(ctx, root, conflict.GetID(), conflict.GetContainedRootObjectID()) } else { return PutRootObject(ctx, root, tName, merged) } } else { if merged == nil { - root, err = RemoveRootObject(ctx, root, conflict.GetID(), conflict.GetRootObjectID()) + root, err = RemoveRootObjectIfExists(ctx, root, conflict.GetID(), conflict.GetContainedRootObjectID()) if err != nil { return nil, err } @@ -491,6 +494,25 @@ func RemoveRootObject(ctx context.Context, root objinterface.RootValue, identifi return coll.UpdateRoot(ctx, root) } +// RemoveRootObjectIfExists removes the matching root object from its respective Collection, returning the updated root. +// If the root object does not exist, then this will not attempt the deletion. +func RemoveRootObjectIfExists(ctx context.Context, root objinterface.RootValue, identifier id.Id, rootObjectID objinterface.RootObjectID) (objinterface.RootValue, error) { + coll, err := LoadCollection(ctx, root, rootObjectID) + if err != nil { + return nil, err + } + exists, err := coll.HasRootObject(ctx, identifier) + if err != nil { + return nil, err + } + if exists { + if err = coll.DropRootObject(ctx, identifier); err != nil { + return nil, err + } + } + return coll.UpdateRoot(ctx, root) +} + // ResolveName returns the fully resolved name of the given item (if the item exists). Also returns the type of the item. func ResolveName(ctx context.Context, root objinterface.RootValue, name doltdb.TableName) (doltdb.TableName, id.Id, objinterface.RootObjectID, error) { var resolvedName doltdb.TableName @@ -524,3 +546,27 @@ func ResolveName(ctx context.Context, root objinterface.RootValue, name doltdb.T return resolvedName, resolvedRawID, resolvedObjID, nil } + +// resolveNameFromObjects resolves the given name on all given objects on all global collections (except for conflicts). +func resolveNameFromObjects(ctx context.Context, name doltdb.TableName, rootObjects []objinterface.RootObject) (doltdb.TableName, id.Id, error) { + var resolvedName doltdb.TableName + resolvedRawID := id.Null + + for i, emptyColl := range globalCollections { + if emptyColl == nil || i == int(objinterface.RootObjectID_Conflicts) { + continue + } + rName, rID, err := emptyColl.ResolveNameFromObjects(ctx, name, rootObjects) + if err != nil { + return doltdb.TableName{}, id.Null, err + } + if rID.IsValid() { + if resolvedRawID != id.Null { + return doltdb.TableName{}, id.Null, fmt.Errorf(`"%s" is ambiguous`, name.String()) + } + resolvedName = rName + resolvedRawID = rID + } + } + return resolvedName, resolvedRawID, nil +} diff --git a/core/rootobject/init.go b/core/rootobject/init.go index a721910aba..c203bfff61 100644 --- a/core/rootobject/init.go +++ b/core/rootobject/init.go @@ -31,6 +31,7 @@ func Init() { conflicts.DeserializeRootObject = DeserializeRootObject conflicts.DiffRootObjects = DiffRootObjects conflicts.GetFieldType = GetFieldType + conflicts.ResolveNameExternal = resolveNameFromObjects conflicts.UpdateField = UpdateField doltdb.RootObjectDiffFromRow = objinterface.DiffFromRow for _, collFuncs := range globalCollections { diff --git a/core/rootobject/objinterface/interfaces.go b/core/rootobject/objinterface/interfaces.go index f9e0a45bfb..e142371e94 100644 --- a/core/rootobject/objinterface/interfaces.go +++ b/core/rootobject/objinterface/interfaces.go @@ -90,6 +90,10 @@ type Collection interface { // LoadCollectionHash loads the Collection hash from the given root. This does not load the entire collection from // the root, and is therefore a bit more performant if only the hash is needed. LoadCollectionHash(ctx context.Context, root RootValue) (hash.Hash, error) + // ResolveNameFromObjects finds the closest matching (or exact) ID for the given name. If an exact match is not + // found, then this may error if the name is ambiguous. This searches through the given root objects rather than the + // ones stored in the collection itself. + ResolveNameFromObjects(ctx context.Context, name doltdb.TableName, rootObjects []RootObject) (doltdb.TableName, id.Id, error) // Serializer returns the serializer associated with this Collection. Serializer() RootObjectSerializer // UpdateRoot updates the Collection in the given root, returning the updated root. diff --git a/core/rootobject/objinterface/root_object.go b/core/rootobject/objinterface/root_object.go index fd1362b545..a00f4d1b35 100644 --- a/core/rootobject/objinterface/root_object.go +++ b/core/rootobject/objinterface/root_object.go @@ -41,6 +41,8 @@ type RootObject interface { type Conflict interface { RootObject doltdb.ConflictRootObject + // GetContainedRootObjectID returns the root object ID of the contained items. + GetContainedRootObjectID() RootObjectID // Diffs returns the diffs for the conflict, along with the merged root object if there are no diffs. Diffs(ctx context.Context) ([]RootObjectDiff, RootObject, error) // FieldType returns the type associated with the given field name. Returns nil if the name does not match a field. diff --git a/core/sequences/collection_funcs.go b/core/sequences/collection_funcs.go index 1a8e592b96..49023efbb8 100644 --- a/core/sequences/collection_funcs.go +++ b/core/sequences/collection_funcs.go @@ -22,6 +22,7 @@ import ( "github.com/dolthub/dolt/go/libraries/doltcore/merge" "github.com/dolthub/dolt/go/store/hash" "github.com/dolthub/dolt/go/store/prolly" + "github.com/dolthub/dolt/go/store/prolly/tree" "github.com/dolthub/doltgresql/core/id" merge2 "github.com/dolthub/doltgresql/core/merge" @@ -145,6 +146,32 @@ func LoadSequences(ctx context.Context, root objinterface.RootValue) (*Collectio }, nil } +// ResolveNameFromObjects implements the interface objinterface.Collection. +func (*Collection) ResolveNameFromObjects(ctx context.Context, name doltdb.TableName, rootObjects []objinterface.RootObject) (doltdb.TableName, id.Id, error) { + // First we'll check if there are any objects to search through in the first place + accessedMap := make(map[id.Sequence]*Sequence) + for _, rootObject := range rootObjects { + if obj, ok := rootObject.(*Sequence); ok { + accessedMap[obj.Id] = obj + } + } + if len(accessedMap) == 0 { + return doltdb.TableName{}, id.Null, nil + } + // There are root objects to search through, so we'll create a temporary store + ns := tree.NewTestNodeStore() + addressMap, err := prolly.NewEmptyAddressMap(ns) + if err != nil { + return doltdb.TableName{}, id.Null, err + } + tempCollection := Collection{ + accessedMap: accessedMap, + underlyingMap: addressMap, + ns: ns, + } + return tempCollection.ResolveName(ctx, name) +} + // Serializer implements the interface objinterface.Collection. func (*Collection) Serializer() objinterface.RootObjectSerializer { return storage diff --git a/core/triggers/collection_funcs.go b/core/triggers/collection_funcs.go index 7ac5fa04a7..0d817cf7b3 100644 --- a/core/triggers/collection_funcs.go +++ b/core/triggers/collection_funcs.go @@ -23,6 +23,7 @@ import ( "github.com/dolthub/dolt/go/store/hash" "github.com/dolthub/dolt/go/store/prolly" + "github.com/dolthub/doltgresql/core/id" "github.com/dolthub/doltgresql/core/rootobject/objinterface" "github.com/dolthub/doltgresql/flatbuffers/gen/serial" ) @@ -94,6 +95,21 @@ func LoadTriggers(ctx context.Context, root objinterface.RootValue) (*Collection return NewCollection(ctx, m, root.NodeStore()) } +// ResolveNameFromObjects implements the interface objinterface.Collection. +func (*Collection) ResolveNameFromObjects(ctx context.Context, name doltdb.TableName, rootObjects []objinterface.RootObject) (doltdb.TableName, id.Id, error) { + tempCollection := Collection{ + accessCache: make(map[id.Trigger]Trigger), + idCache: make([]id.Trigger, 0, len(rootObjects)), + } + for _, rootObject := range rootObjects { + if obj, ok := rootObject.(Trigger); ok { + tempCollection.accessCache[obj.ID] = obj + tempCollection.idCache = append(tempCollection.idCache, obj.ID) + } + } + return tempCollection.ResolveName(ctx, name) +} + // Serializer implements the interface objinterface.Collection. func (*Collection) Serializer() objinterface.RootObjectSerializer { return storage diff --git a/core/typecollection/collection_funcs.go b/core/typecollection/collection_funcs.go index fe966ce615..85dbe05a3f 100644 --- a/core/typecollection/collection_funcs.go +++ b/core/typecollection/collection_funcs.go @@ -22,6 +22,7 @@ import ( "github.com/dolthub/dolt/go/libraries/doltcore/merge" "github.com/dolthub/dolt/go/store/hash" "github.com/dolthub/dolt/go/store/prolly" + "github.com/dolthub/dolt/go/store/prolly/tree" "github.com/dolthub/doltgresql/core/id" merge2 "github.com/dolthub/doltgresql/core/merge" @@ -134,6 +135,32 @@ func LoadTypes(ctx context.Context, root objinterface.RootValue) (*TypeCollectio }, nil } +// ResolveNameFromObjects implements the interface objinterface.Collection. +func (*TypeCollection) ResolveNameFromObjects(ctx context.Context, name doltdb.TableName, rootObjects []objinterface.RootObject) (doltdb.TableName, id.Id, error) { + // First we'll check if there are any objects to search through in the first place + accessedMap := make(map[id.Type]*pgtypes.DoltgresType) + for _, rootObject := range rootObjects { + if obj, ok := rootObject.(TypeWrapper); ok && obj.Type != nil { + accessedMap[obj.Type.ID] = obj.Type + } + } + if len(accessedMap) == 0 { + return doltdb.TableName{}, id.Null, nil + } + // There are root objects to search through, so we'll create a temporary store + ns := tree.NewTestNodeStore() + addressMap, err := prolly.NewEmptyAddressMap(ns) + if err != nil { + return doltdb.TableName{}, id.Null, err + } + tempCollection := TypeCollection{ + accessedMap: accessedMap, + underlyingMap: addressMap, + ns: ns, + } + return tempCollection.ResolveName(ctx, name) +} + // Serializer implements the interface objinterface.Collection. func (*TypeCollection) Serializer() objinterface.RootObjectSerializer { return storage diff --git a/go.mod b/go.mod index 6a8adad7da..204af9f224 100644 --- a/go.mod +++ b/go.mod @@ -6,11 +6,11 @@ require ( github.com/PuerkitoBio/goquery v1.8.1 github.com/cockroachdb/apd/v2 v2.0.3-0.20200518165714-d020e156310a github.com/cockroachdb/errors v1.7.5 - github.com/dolthub/dolt/go v0.40.5-0.20250806114231-360244221c59 + github.com/dolthub/dolt/go v0.40.5-0.20250808100539-b53e3665aff6 github.com/dolthub/eventsapi_schema v0.0.0-20250725194025-a087efa1ee55 github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 github.com/dolthub/go-icu-regex v0.0.0-20250327004329-6799764f2dad - github.com/dolthub/go-mysql-server v0.20.1-0.20250805190315-b5e26987dc7e + github.com/dolthub/go-mysql-server v0.20.1-0.20250807172251-c76b4ab0b9c8 github.com/dolthub/sqllogictest/go v0.0.0-20240618184124-ca47f9354216 github.com/dolthub/vitess v0.0.0-20250730174048-497aebb8cea7 github.com/fatih/color v1.13.0 diff --git a/go.sum b/go.sum index 9634beb3ca..c37540fa6b 100644 --- a/go.sum +++ b/go.sum @@ -273,8 +273,8 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dolthub/aws-sdk-go-ini-parser v0.0.0-20250305001723-2821c37f6c12 h1:IdqX7J8vi/Kn3T3Ee0VzqnLqwFmgA2hr8WZETPcQjfM= github.com/dolthub/aws-sdk-go-ini-parser v0.0.0-20250305001723-2821c37f6c12/go.mod h1:rN7X8BHwkjPcfMQQ2QTAq/xM3leUSGLfb+1Js7Y6TVo= -github.com/dolthub/dolt/go v0.40.5-0.20250806114231-360244221c59 h1:B9WYNMOys9FgUZwBXAfv43zMhx1h5zWHbimyzb2f0bg= -github.com/dolthub/dolt/go v0.40.5-0.20250806114231-360244221c59/go.mod h1:D0rWMuTgsIFzEPXi+d7tiGIRGrzqLsC72A9d77CqWGo= +github.com/dolthub/dolt/go v0.40.5-0.20250808100539-b53e3665aff6 h1:80ajGg0s/fwpJCjrvfRiW0vHN1xsbDItmduvjzYROsc= +github.com/dolthub/dolt/go v0.40.5-0.20250808100539-b53e3665aff6/go.mod h1:pP/jZVfosnKfvpsxx2YZODFkfhtMdGtRHXWmT3rtIW8= github.com/dolthub/eventsapi_schema v0.0.0-20250725194025-a087efa1ee55 h1:LdtiPD8IJ+M2XckvfQ/aLG34lET1shz+WMccGBhZRLM= github.com/dolthub/eventsapi_schema v0.0.0-20250725194025-a087efa1ee55/go.mod h1:CoDLfgPqHyBtth0Cp+fi/CmC4R81zJNX4wPjShdZ+Bw= github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 h1:u3PMzfF8RkKd3lB9pZ2bfn0qEG+1Gms9599cr0REMww= @@ -283,8 +283,8 @@ github.com/dolthub/fslock v0.0.3 h1:iLMpUIvJKMKm92+N1fmHVdxJP5NdyDK5bK7z7Ba2s2U= github.com/dolthub/fslock v0.0.3/go.mod h1:QWql+P17oAAMLnL4HGB5tiovtDuAjdDTPbuqx7bYfa0= github.com/dolthub/go-icu-regex v0.0.0-20250327004329-6799764f2dad h1:66ZPawHszNu37VPQckdhX1BPPVzREsGgNxQeefnlm3g= github.com/dolthub/go-icu-regex v0.0.0-20250327004329-6799764f2dad/go.mod h1:ylU4XjUpsMcvl/BKeRRMXSH7e7WBrPXdSLvnRJYrxEA= -github.com/dolthub/go-mysql-server v0.20.1-0.20250805190315-b5e26987dc7e h1:Y60WgC41nCXZYiDluURi4vmvDevlpF4sEesJqHLPdus= -github.com/dolthub/go-mysql-server v0.20.1-0.20250805190315-b5e26987dc7e/go.mod h1:D/E/y9q6i4mryN12JhvaKlFZnSSWD1X1tx+CFsUcgp8= +github.com/dolthub/go-mysql-server v0.20.1-0.20250807172251-c76b4ab0b9c8 h1:MRwXXSGmTxG2nNQzWeFs4AOevCpn6fTVdrDX5+1rZhM= +github.com/dolthub/go-mysql-server v0.20.1-0.20250807172251-c76b4ab0b9c8/go.mod h1:D/E/y9q6i4mryN12JhvaKlFZnSSWD1X1tx+CFsUcgp8= github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63 h1:OAsXLAPL4du6tfbBgK0xXHZkOlos63RdKYS3Sgw/dfI= github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63/go.mod h1:lV7lUeuDhH5thVGDCKXbatwKy2KW80L4rMT46n+Y2/Q= github.com/dolthub/ishell v0.0.0-20240701202509-2b217167d718 h1:lT7hE5k+0nkBdj/1UOSFwjWpNxf+LCApbRHgnCA17XE= diff --git a/testing/go/conflicts_root_object_test.go b/testing/go/conflicts_root_object_test.go index 8fad2f5f51..9d1f3320ea 100644 --- a/testing/go/conflicts_root_object_test.go +++ b/testing/go/conflicts_root_object_test.go @@ -560,7 +560,6 @@ func TestConflictsRootObject(t *testing.T) { }, { Name: `Function deleted "ours" updated "theirs", chose "ours"`, - Skip: true, // TODO: there's a bug dealing with root objects being incorrectly treated as tables SetUpScript: []string{`CREATE FUNCTION interpreted_example(input TEXT) RETURNS TEXT AS $$ BEGIN RETURN '1' || input; END; $$ LANGUAGE plpgsql;`}, Assertions: []ScriptTestAssertion{ { @@ -637,7 +636,6 @@ func TestConflictsRootObject(t *testing.T) { }, { Name: `Function deleted "ours" updated "theirs", chose "theirs"`, - Skip: true, // TODO: there's a bug dealing with root objects being incorrectly treated as tables SetUpScript: []string{`CREATE FUNCTION interpreted_example(input TEXT) RETURNS TEXT AS $$ BEGIN RETURN '1' || input; END; $$ LANGUAGE plpgsql;`}, Assertions: []ScriptTestAssertion{ { @@ -716,7 +714,6 @@ func TestConflictsRootObject(t *testing.T) { }, { Name: `Function deleted "ours" updated "theirs", chose "ancestor"`, - Skip: true, // TODO: there's a bug dealing with root objects being incorrectly treated as tables SetUpScript: []string{`CREATE FUNCTION interpreted_example(input TEXT) RETURNS TEXT AS $$ BEGIN RETURN '1' || input; END; $$ LANGUAGE plpgsql;`}, Assertions: []ScriptTestAssertion{ { @@ -795,7 +792,6 @@ func TestConflictsRootObject(t *testing.T) { }, { Name: `Function deleted "theirs" updated "ours", chose "ours"`, - Skip: true, // TODO: there's a bug dealing with root objects being incorrectly treated as tables SetUpScript: []string{`CREATE FUNCTION interpreted_example(input TEXT) RETURNS TEXT AS $$ BEGIN RETURN '1' || input; END; $$ LANGUAGE plpgsql;`}, Assertions: []ScriptTestAssertion{ { @@ -853,16 +849,16 @@ func TestConflictsRootObject(t *testing.T) { { Query: `SELECT base_value, our_value, our_diff_type, their_value, their_diff_type, dolt_conflict_id FROM "dolt_conflicts_interpreted_example(text)";`, Expected: []sql.Row{ - {"ancestor", nil, "deleted", "theirs", "modified", "root_object"}, + {"ancestor", "ours", "modified", nil, "deleted", "root_object"}, }, }, - { + { // This is effectively a no-op as it doesn't produce an actual change (this verifies the behavior) Query: `UPDATE "dolt_conflicts_interpreted_example(text)" SET our_value = 'ours';`, Expected: []sql.Row{}, }, - { // Updating to "ours" will delete the conflicts table since we're keeping our original root object - Query: `DELETE FROM "dolt_conflicts_interpreted_example(text)";`, - ExpectedErr: `table not found`, + { // This actually enforces that we've chosen "ours", since we're deleting the entry + Query: `DELETE FROM "dolt_conflicts_interpreted_example(text)";`, + Expected: []sql.Row{}, }, { Query: "SELECT interpreted_example('12');", @@ -874,7 +870,6 @@ func TestConflictsRootObject(t *testing.T) { }, { Name: `Function deleted "theirs" updated "ours", chose "theirs"`, - Skip: true, // TODO: there's a bug dealing with root objects being incorrectly treated as tables SetUpScript: []string{`CREATE FUNCTION interpreted_example(input TEXT) RETURNS TEXT AS $$ BEGIN RETURN '1' || input; END; $$ LANGUAGE plpgsql;`}, Assertions: []ScriptTestAssertion{ { @@ -932,7 +927,7 @@ func TestConflictsRootObject(t *testing.T) { { Query: `SELECT base_value, our_value, our_diff_type, their_value, their_diff_type, dolt_conflict_id FROM "dolt_conflicts_interpreted_example(text)";`, Expected: []sql.Row{ - {"ancestor", nil, "deleted", "theirs", "modified", "root_object"}, + {"ancestor", "ours", "modified", nil, "deleted", "root_object"}, }, }, { @@ -951,7 +946,6 @@ func TestConflictsRootObject(t *testing.T) { }, { Name: `Function deleted "theirs" updated "ours", chose "ancestor"`, - Skip: true, // TODO: there's a bug dealing with root objects being incorrectly treated as tables SetUpScript: []string{`CREATE FUNCTION interpreted_example(input TEXT) RETURNS TEXT AS $$ BEGIN RETURN '1' || input; END; $$ LANGUAGE plpgsql;`}, Assertions: []ScriptTestAssertion{ { @@ -1009,7 +1003,7 @@ func TestConflictsRootObject(t *testing.T) { { Query: `SELECT base_value, our_value, our_diff_type, their_value, their_diff_type, dolt_conflict_id FROM "dolt_conflicts_interpreted_example(text)";`, Expected: []sql.Row{ - {"ancestor", nil, "deleted", "theirs", "modified", "root_object"}, + {"ancestor", "ours", "modified", nil, "deleted", "root_object"}, }, }, {