mirror of
https://github.com/dolthub/dolt.git
synced 2025-12-30 08:50:01 -06:00
fix error message for duplicate unique key violation on out of band types (#8632)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user