Skip to content

Commit 9a0413b

Browse files
authored
expression: make LPAD/RPAD return an empty string for an empty padstr (pingcap#59734)
close pingcap#59447
1 parent 1c90ae7 commit 9a0413b

File tree

5 files changed

+56
-12
lines changed

5 files changed

+56
-12
lines changed

pkg/expression/builtin_string.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -2205,9 +2205,12 @@ func (b *builtinLpadSig) evalString(ctx EvalContext, row chunk.Row) (string, boo
22052205
}
22062206
padLength := len(padStr)
22072207

2208-
if targetLength < 0 || targetLength > b.tp.GetFlen() || (byteLength < targetLength && padLength == 0) {
2208+
if targetLength < 0 || targetLength > b.tp.GetFlen() {
22092209
return "", true, nil
22102210
}
2211+
if byteLength < targetLength && padLength == 0 {
2212+
return "", false, nil
2213+
}
22112214

22122215
if tailLen := targetLength - byteLength; tailLen > 0 {
22132216
repeatCount := tailLen/padLength + 1
@@ -2253,9 +2256,12 @@ func (b *builtinLpadUTF8Sig) evalString(ctx EvalContext, row chunk.Row) (string,
22532256
}
22542257
padLength := len([]rune(padStr))
22552258

2256-
if targetLength < 0 || targetLength*4 > b.tp.GetFlen() || (runeLength < targetLength && padLength == 0) {
2259+
if targetLength < 0 || targetLength*4 > b.tp.GetFlen() {
22572260
return "", true, nil
22582261
}
2262+
if runeLength < targetLength && padLength == 0 {
2263+
return "", false, nil
2264+
}
22592265

22602266
if tailLen := targetLength - runeLength; tailLen > 0 {
22612267
repeatCount := tailLen/padLength + 1
@@ -2329,9 +2335,12 @@ func (b *builtinRpadSig) evalString(ctx EvalContext, row chunk.Row) (string, boo
23292335
}
23302336
padLength := len(padStr)
23312337

2332-
if targetLength < 0 || targetLength > b.tp.GetFlen() || (byteLength < targetLength && padLength == 0) {
2338+
if targetLength < 0 || targetLength > b.tp.GetFlen() {
23332339
return "", true, nil
23342340
}
2341+
if byteLength < targetLength && padLength == 0 {
2342+
return "", false, nil
2343+
}
23352344

23362345
if tailLen := targetLength - byteLength; tailLen > 0 {
23372346
repeatCount := tailLen/padLength + 1
@@ -2377,9 +2386,12 @@ func (b *builtinRpadUTF8Sig) evalString(ctx EvalContext, row chunk.Row) (string,
23772386
}
23782387
padLength := len([]rune(padStr))
23792388

2380-
if targetLength < 0 || targetLength*4 > b.tp.GetFlen() || (runeLength < targetLength && padLength == 0) {
2389+
if targetLength < 0 || targetLength*4 > b.tp.GetFlen() {
23812390
return "", true, nil
23822391
}
2392+
if runeLength < targetLength && padLength == 0 {
2393+
return "", false, nil
2394+
}
23832395

23842396
if tailLen := targetLength - runeLength; tailLen > 0 {
23852397
repeatCount := tailLen/padLength + 1

pkg/expression/builtin_string_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -1561,13 +1561,13 @@ func TestLpad(t *testing.T) {
15611561
{"hi", 0, "?", ""},
15621562
{"hi", -1, "?", nil},
15631563
{"hi", 1, "", "h"},
1564-
{"hi", 5, "", nil},
1564+
{"hi", 5, "", ""},
15651565
{"hi", 5, "ab", "abahi"},
15661566
{"hi", 6, "ab", "ababhi"},
15671567
{"中文", 5, "字符", "字符字中文"},
15681568
{"中文", 1, "a", "中"},
15691569
{"中文", -5, "字符", nil},
1570-
{"中文", 10, "", nil},
1570+
{"中文", 10, "", ""},
15711571
}
15721572
fc := funcs[ast.Lpad]
15731573
for _, test := range tests {
@@ -1601,13 +1601,13 @@ func TestRpad(t *testing.T) {
16011601
{"hi", 0, "?", ""},
16021602
{"hi", -1, "?", nil},
16031603
{"hi", 1, "", "h"},
1604-
{"hi", 5, "", nil},
1604+
{"hi", 5, "", ""},
16051605
{"hi", 5, "ab", "hiaba"},
16061606
{"hi", 6, "ab", "hiabab"},
16071607
{"中文", 5, "字符", "中文字符字"},
16081608
{"中文", 1, "a", "中"},
16091609
{"中文", -5, "字符", nil},
1610-
{"中文", 10, "", nil},
1610+
{"中文", 10, "", ""},
16111611
}
16121612
fc := funcs[ast.Rpad]
16131613
for _, test := range tests {

pkg/expression/builtin_string_vec.go

+20-4
Original file line numberDiff line numberDiff line change
@@ -1024,10 +1024,14 @@ func (b *builtinLpadSig) vecEvalString(ctx EvalContext, input *chunk.Chunk, resu
10241024
strLength := len(str)
10251025
padStr := padBuf.GetString(i)
10261026
padLength := len(padStr)
1027-
if targetLength < 0 || targetLength > b.tp.GetFlen() || (strLength < targetLength && padLength == 0) {
1027+
if targetLength < 0 || targetLength > b.tp.GetFlen() {
10281028
result.AppendNull()
10291029
continue
10301030
}
1031+
if strLength < targetLength && padLength == 0 {
1032+
result.AppendString("")
1033+
continue
1034+
}
10311035
if tailLen := targetLength - strLength; tailLen > 0 {
10321036
repeatCount := tailLen/padLength + 1
10331037
str = strings.Repeat(padStr, repeatCount)[:tailLen] + str
@@ -1095,10 +1099,14 @@ func (b *builtinLpadUTF8Sig) vecEvalString(ctx EvalContext, input *chunk.Chunk,
10951099
runeLength := len([]rune(str))
10961100
padLength := len([]rune(padStr))
10971101

1098-
if targetLength < 0 || targetLength*4 > b.tp.GetFlen() || (runeLength < targetLength && padLength == 0) {
1102+
if targetLength < 0 || targetLength*4 > b.tp.GetFlen() {
10991103
result.AppendNull()
11001104
continue
11011105
}
1106+
if runeLength < targetLength && padLength == 0 {
1107+
result.AppendString("")
1108+
continue
1109+
}
11021110
if tailLen := targetLength - runeLength; tailLen > 0 {
11031111
repeatCount := tailLen/padLength + 1
11041112
str = string([]rune(strings.Repeat(padStr, repeatCount))[:tailLen]) + str
@@ -1485,10 +1493,14 @@ func (b *builtinRpadSig) vecEvalString(ctx EvalContext, input *chunk.Chunk, resu
14851493
strLength := len(str)
14861494
padStr := padBuf.GetString(i)
14871495
padLength := len(padStr)
1488-
if targetLength < 0 || targetLength > b.tp.GetFlen() || (strLength < targetLength && padLength == 0) {
1496+
if targetLength < 0 || targetLength > b.tp.GetFlen() {
14891497
result.AppendNull()
14901498
continue
14911499
}
1500+
if strLength < targetLength && padLength == 0 {
1501+
result.AppendString("")
1502+
continue
1503+
}
14921504
if tailLen := targetLength - strLength; tailLen > 0 {
14931505
repeatCount := tailLen/padLength + 1
14941506
str = str + strings.Repeat(padStr, repeatCount)
@@ -2619,10 +2631,14 @@ func (b *builtinRpadUTF8Sig) vecEvalString(ctx EvalContext, input *chunk.Chunk,
26192631
runeLength := len([]rune(str))
26202632
padLength := len([]rune(padStr))
26212633

2622-
if targetLength < 0 || targetLength*4 > b.tp.GetFlen() || (runeLength < targetLength && padLength == 0) {
2634+
if targetLength < 0 || targetLength*4 > b.tp.GetFlen() {
26232635
result.AppendNull()
26242636
continue
26252637
}
2638+
if runeLength < targetLength && padLength == 0 {
2639+
result.AppendString("")
2640+
continue
2641+
}
26262642
if tailLen := targetLength - runeLength; tailLen > 0 {
26272643
repeatCount := tailLen/padLength + 1
26282644
str = str + strings.Repeat(padStr, repeatCount)

tests/integrationtest/r/expression/builtin.result

+12
Original file line numberDiff line numberDiff line change
@@ -1616,9 +1616,21 @@ INSERT INTO t SELECT "中文", "abc";
16161616
SELECT LPAD(a, 11, "a"), LPAD(b, 2, "xx") FROM t;
16171617
LPAD(a, 11, "a") LPAD(b, 2, "xx")
16181618
a中文 ab
1619+
SELECT LPAD("abc", 5, "");
1620+
LPAD("abc", 5, "")
1621+
1622+
SELECT LPAD(a, 11, ""), LPAD(b, 5, "") FROM t;
1623+
LPAD(a, 11, "") LPAD(b, 5, "")
1624+
16191625
SELECT RPAD(a, 11, "a"), RPAD(b, 2, "xx") FROM t;
16201626
RPAD(a, 11, "a") RPAD(b, 2, "xx")
16211627
中文a ab
1628+
SELECT RPAD("abc", 5, "");
1629+
RPAD("abc", 5, "")
1630+
1631+
SELECT RPAD(a, 11, ""), RPAD(b, 5, "") FROM t;
1632+
RPAD(a, 11, "") RPAD(b, 5, "")
1633+
16221634
drop table if exists t;
16231635
create table t(a int, b double, c datetime, d time, e char(20), f bit(10));
16241636
insert into t values(1, 1.1, "2017-01-01 12:01:01", "12:01:01", "abcdef", 0b10101);

tests/integrationtest/t/expression/builtin.test

+4
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,11 @@ DROP TABLE IF EXISTS t;
719719
CREATE TABLE t(a BINARY(10), b CHAR(10));
720720
INSERT INTO t SELECT "中文", "abc";
721721
SELECT LPAD(a, 11, "a"), LPAD(b, 2, "xx") FROM t;
722+
SELECT LPAD("abc", 5, "");
723+
SELECT LPAD(a, 11, ""), LPAD(b, 5, "") FROM t;
722724
SELECT RPAD(a, 11, "a"), RPAD(b, 2, "xx") FROM t;
725+
SELECT RPAD("abc", 5, "");
726+
SELECT RPAD(a, 11, ""), RPAD(b, 5, "") FROM t;
723727

724728
# TestStringBuiltin
725729
drop table if exists t;

0 commit comments

Comments
 (0)