fix error message for duplicate unique key violation on out of band types (#8632)

This commit is contained in:
James Cor
2024-12-03 15:12:43 -08:00
committed by GitHub
parent 884ee1e1bb
commit 192e1c1be5
4 changed files with 54 additions and 8 deletions

View File

@@ -7135,6 +7135,23 @@ var DoltIndexPrefixScripts = []queries.ScriptTest{
},
},
},
{
Name: "text and blob key errors",
SetUpScript: []string{
"create table t (t text, b blob, unique(t(4)), unique(b));",
"insert into t values ('hello', 'goodbye');",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "insert into t values('hello123', 'something different');",
ExpectedErrStr: "duplicate unique key given: [hell]",
},
{
Query: "insert into t values('something different', 'goodbye');",
ExpectedErrStr: "duplicate unique key given: [goodbye]",
},
},
},
}
// DoltCallAsOf are tests of using CALL ... AS OF using commits

View File

@@ -16,6 +16,7 @@ package writer
import (
"context"
"fmt"
"io"
"strings"
@@ -125,7 +126,12 @@ func (m prollyIndexWriter) ValidateKeyViolations(ctx context.Context, sqlRow sql
if err != nil {
return err
} else if ok {
keyStr := FormatKeyForUniqKeyErr(k, m.keyBld.Desc)
remappedSqlRow := make(sql.Row, len(sqlRow))
for to := range m.keyMap {
from := m.keyMap.MapOrdinal(to)
remappedSqlRow[to] = sqlRow[from]
}
keyStr := FormatKeyForUniqKeyErr(k, m.keyBld.Desc, remappedSqlRow)
return m.uniqueKeyError(ctx, keyStr, k, true)
}
return nil
@@ -182,7 +188,12 @@ func (m prollyIndexWriter) Update(ctx context.Context, oldRow sql.Row, newRow sq
if err != nil {
return err
} else if ok {
keyStr := FormatKeyForUniqKeyErr(newKey, m.keyBld.Desc)
remappedSqlRow := make(sql.Row, len(newRow))
for to := range m.keyMap {
from := m.keyMap.MapOrdinal(to)
remappedSqlRow[to] = newRow[from]
}
keyStr := FormatKeyForUniqKeyErr(newKey, m.keyBld.Desc, remappedSqlRow)
return m.uniqueKeyError(ctx, keyStr, newKey, true)
}
@@ -354,8 +365,13 @@ func (m prollySecondaryIndexWriter) checkForUniqueKeyErr(ctx context.Context, sq
}
existingPK := m.pkBld.Build(sharePool)
remappedSqlRow := make(sql.Row, m.idxCols)
for to := range m.keyMap[:m.idxCols] {
from := m.keyMap.MapOrdinal(to)
remappedSqlRow[to] = m.trimKeyPart(to, sqlRow[from])
}
return secondaryUniqueKeyError{
keyStr: FormatKeyForUniqKeyErr(key, desc),
keyStr: FormatKeyForUniqKeyErr(key, desc, remappedSqlRow),
existingKey: existingPK,
}
}
@@ -413,7 +429,7 @@ func (m prollySecondaryIndexWriter) IterRange(ctx context.Context, rng prolly.Ra
// FormatKeyForUniqKeyErr formats the given tuple |key| using |d|. The resulting
// string is suitable for use in a sql.UniqueKeyError
func FormatKeyForUniqKeyErr(key val.Tuple, d val.TupleDesc) string {
func FormatKeyForUniqKeyErr(key val.Tuple, d val.TupleDesc, sqlRow sql.Row) string {
var sb strings.Builder
sb.WriteString("[")
seenOne := false
@@ -422,7 +438,13 @@ func FormatKeyForUniqKeyErr(key val.Tuple, d val.TupleDesc) string {
sb.WriteString(",")
}
seenOne = true
sb.WriteString(d.FormatValue(i, key.GetField(i)))
switch d.Types[i].Enc {
// address encodings should be printed as strings
case val.BytesAddrEnc, val.StringAddrEnc:
sb.WriteString(fmt.Sprintf("%s", sqlRow[i]))
default:
sb.WriteString(d.FormatValue(i, key.GetField(i)))
}
}
sb.WriteString("]")
return sb.String()

View File

@@ -258,7 +258,7 @@ func (writer prollyKeylessSecondaryWriter) Insert(ctx context.Context, sqlRow sq
if writer.unique {
prefixKey := writer.prefixBld.Build(sharePool)
err := writer.checkForUniqueKeyError(ctx, prefixKey)
err := writer.checkForUniqueKeyError(ctx, prefixKey, sqlRow)
if err != nil {
return err
}
@@ -269,7 +269,7 @@ func (writer prollyKeylessSecondaryWriter) Insert(ctx context.Context, sqlRow sq
return writer.mut.Put(ctx, indexKey, val.EmptyTuple)
}
func (writer prollyKeylessSecondaryWriter) checkForUniqueKeyError(ctx context.Context, prefixKey val.Tuple) error {
func (writer prollyKeylessSecondaryWriter) checkForUniqueKeyError(ctx context.Context, prefixKey val.Tuple, sqlRow sql.Row) error {
for i := 0; i < writer.prefixBld.Desc.Count(); i++ {
if writer.prefixBld.Desc.IsNull(i, prefixKey) {
return nil
@@ -286,7 +286,12 @@ func (writer prollyKeylessSecondaryWriter) checkForUniqueKeyError(ctx context.Co
return err
}
if err == nil {
keyStr := FormatKeyForUniqKeyErr(prefixKey, writer.prefixBld.Desc)
remappedSqlRow := make(sql.Row, len(sqlRow))
for to := range writer.keyMap {
from := writer.keyMap.MapOrdinal(to)
remappedSqlRow[to] = writer.trimKeyPart(to, sqlRow[from])
}
keyStr := FormatKeyForUniqKeyErr(prefixKey, writer.prefixBld.Desc, remappedSqlRow)
writer.hashBld.PutRaw(0, k.GetField(k.Count()-1))
existingKey := writer.hashBld.Build(sharePool)
return secondaryUniqueKeyError{keyStr: keyStr, existingKey: existingKey}

View File

@@ -636,6 +636,8 @@ func (td TupleDesc) formatValue(enc Encoding, i int, value []byte) string {
return hex.EncodeToString(value)
case BytesAddrEnc:
return hex.EncodeToString(value)
case StringAddrEnc:
return hex.EncodeToString(value)
case CommitAddrEnc:
return hex.EncodeToString(value)
case CellEnc: