diff --git a/pkg/sql/logictest/testdata/logic_test/update b/pkg/sql/logictest/testdata/logic_test/update index 8483a491cad3..ada5aba89fc3 100644 --- a/pkg/sql/logictest/testdata/logic_test/update +++ b/pkg/sql/logictest/testdata/logic_test/update @@ -510,3 +510,20 @@ UPDATE t32477 SET x = rank(x) OVER () statement error generator functions are not allowed in UPDATE SET UPDATE t32477 SET x = generate_series(1,2) + +#regression test for #32054 +subtest empty_update_subquery + +statement ok +CREATE TABLE t32054(x,y) AS SELECT 1,2 + +statement ok +CREATE TABLE t32054_empty(x INT, y INT) + +statement ok +UPDATE t32054 SET (x,y) = (SELECT x,y FROM t32054_empty) + +query II +SELECT * FROM t32054 +---- +NULL NULL diff --git a/pkg/sql/update.go b/pkg/sql/update.go index 4b8468faf28d..d58c9722d9ec 100644 --- a/pkg/sql/update.go +++ b/pkg/sql/update.go @@ -332,10 +332,15 @@ func (p *planner) Update( colIdx := render.addOrReuseRender(col, expr, false) - sourceSlots = append(sourceSlots, tupleSlot{ + tSlot := tupleSlot{ columns: updateCols[currentUpdateIdx : currentUpdateIdx+len(setExpr.Names)], + emptySlot: make(tree.Datums, len(setExpr.Names)), sourceIndex: colIdx, - }) + } + for i := range tSlot.emptySlot { + tSlot.emptySlot[i] = tree.DNull + } + sourceSlots = append(sourceSlots, tSlot) currentUpdateIdx += len(setExpr.Names) default: @@ -762,9 +767,15 @@ type sourceSlot interface { type tupleSlot struct { columns []sqlbase.ColumnDescriptor sourceIndex int + // emptySlot is to be returned when the source subquery + // returns no rows. + emptySlot tree.Datums } func (ts tupleSlot) extractValues(row tree.Datums) tree.Datums { + if row[ts.sourceIndex] == tree.DNull { + return ts.emptySlot + } return row[ts.sourceIndex].(*tree.DTuple).D }