Skip to content

Commit

Permalink
sql: fix cast from string to array with width
Browse files Browse the repository at this point in the history
The code that performs a cast from string to array doesn't take into
account the width of the string type it is producing. This doesn't
show up when the input is a literal constant because the constant is
first parsed as an array of (vanilla) strings which is then subjected
to a cast (to array of strings with width).

Fixes #50132.

Release note (bug fix): Fixed some cases where casting a string to a
width-limited string array was not truncating the string.
  • Loading branch information
RaduBerinde committed Jun 13, 2020
1 parent ae7d20e commit d5d9181
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
11 changes: 11 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/array
Expand Up @@ -173,6 +173,17 @@ SELECT '{hello, a🐛b🏠c}'::VARCHAR(2)[]
----
{he,a🐛}

# Regression test for #50132.
statement ok
CREATE TABLE hello (s STRING);
INSERT INTO hello VALUES ('{hello}'), ('{hello,a🐛b🏠c}')

query T rowsort
SELECT s::VARCHAR(2)[] FROM hello
----
{he}
{he,a🐛}

# array casting

query T
Expand Down
7 changes: 7 additions & 0 deletions pkg/sql/sem/tree/parse_string.go
Expand Up @@ -12,6 +12,7 @@ package tree

import (
"github.com/cockroachdb/cockroach/pkg/sql/types"
"github.com/cockroachdb/cockroach/pkg/util"
"github.com/cockroachdb/errors"
)

Expand Down Expand Up @@ -49,6 +50,12 @@ func ParseAndRequireString(t *types.T, s string, ctx ParseTimeContext) (Datum, e
i, err := ParseDInt(s)
return NewDOid(*i), err
case types.StringFamily:
// If the string type specifies a limit we truncate to that limit:
// 'hello'::CHAR(2) -> 'he'
// This is true of all the string type variants.
if t.Width() > 0 {
s = util.TruncateString(s, int(t.Width()))
}
return NewDString(s), nil
case types.TimeFamily:
return ParseDTime(ctx, s, TimeFamilyPrecisionToRoundDuration(t.Precision()))
Expand Down
11 changes: 11 additions & 0 deletions pkg/sql/sem/tree/testdata/eval/cast
Expand Up @@ -1070,3 +1070,14 @@ eval
'-10'::interval::decimal
----
-10.000000000

eval
'{hello,a🐛b🏠c}'::VARCHAR(2)[]
----
ARRAY['he',e'a\U0001F41B']

# Test the same cast, but not with a literal constant (see #50132).
eval
('{he' || ',a🐛b🏠}')::VARCHAR(2)[]
----
ARRAY['he',e'a\U0001F41B']

0 comments on commit d5d9181

Please sign in to comment.