Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 51 additions & 20 deletions pkg/sql/logictest/testdata/logic_test/array
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,7 @@ SELECT ARRAY(VALUES (1),(2),(1))
----
{1,2,1}

# This query works in local config but fails in distributed config since the
# support for nested arrays is incomplete.
onlyif config #32252 local
query T
SELECT ARRAY(VALUES (ARRAY[1]))
----
{"{1}"}

onlyif config #32252 fakedist
query error unimplemented: nested arrays are not fully supported.*\nHINT.*\n.*32552
query error pgcode 0A000 arrays of int\[\] not allowed.*\nHINT.*\n.*32552
SELECT ARRAY(VALUES (ARRAY[1]))

query T
Expand Down Expand Up @@ -485,16 +476,7 @@ DROP TABLE boundedtable
statement error .*unimplemented.*\nHINT.*\n.*32552
CREATE TABLE badtable (b INT[][])

# This query works in local config but fails in distributed config since the
# support for nested arrays is incomplete.
onlyif config #32252 local
query T
SELECT ARRAY[ARRAY[1,2,3]]
----
{"{1,2,3}"}

onlyif config #32552 fakedist
query error unimplemented: nested arrays are not fully supported.*\nHINT.*\n.*32552
query error pgcode 0A000 arrays of int\[\] not allowed.*\nHINT.*\n.*32552
SELECT ARRAY[ARRAY[1,2,3]]

# The postgres-compat aliases should be disallowed.
Expand Down Expand Up @@ -2560,3 +2542,52 @@ SELECT width_bucket(true, '{}');

query error pgcode 42804 could not determine polymorphic type because input has type unknown
SELECT array_to_string('{}', 'foo');

subtest regression_146717

# Multidimensional constructors must reject unsupported array elements before
# they can be formatted as an array of strings instead of a nested array.
query error pgcode 0A000 arrays of string\[\] not allowed.*\nHINT.*\n.*32552
SELECT ARRAY[ARRAY['a']]::TEXT;

query error pgcode 0A000 arrays of string\[\] not allowed
SELECT ARRAY[['a']]::TEXT;

query error pgcode 0A000 arrays of string\[\] not allowed
SELECT ARRAY(SELECT ARRAY['a'])::TEXT;

query error pgcode 0A000 arrays of string\[\] not allowed
SELECT ARRAY(VALUES (ARRAY['a']))::TEXT;

query error pgcode 0A000 arrays of int\[\] not allowed
SELECT ARRAY[ARRAY[1, 2]];

query error pgcode 0A000 arrays of int\[\] not allowed
SELECT ARRAY[ARRAY[]::INT[]];

query error pgcode 0A000 arrays of string\[\] not allowed
SELECT ARRAY[NULL::TEXT[]];

query error pgcode 0A000 arrays of int\[\] not allowed
SELECT ARRAY(SELECT ARRAY[1] WHERE false);

# Braces in scalar strings and array-valued tuple fields are not dimensions.
query T
SELECT ARRAY['{a}']::TEXT;
----
{"{a}"}

query T
SELECT ARRAY[ROW(ARRAY['a'])]::TEXT;
----
{"({a})"}

query T
SELECT ARRAY[]::TEXT[]::TEXT;
----
{}

query T
SELECT ARRAY[NULL::TEXT]::TEXT;
----
{NULL}
6 changes: 3 additions & 3 deletions pkg/sql/opt/norm/testdata/rules/join
Original file line number Diff line number Diff line change
Expand Up @@ -2713,13 +2713,13 @@ values
# EliminateJoinNoColsLeft
# --------------------------------------------------
norm expect=EliminateJoinNoColsLeft
SELECT unnest(ARRAY[[1,2,3],[4,5]])
SELECT unnest(ARRAY[1,2])
----
values
├── columns: unnest:1!null
├── cardinality: [2 - 2]
├── (ARRAY[1,2,3],)
└── (ARRAY[4,5],)
├── (1,)
└── (2,)

# --------------------------------------------------
# EliminateJoinNoColsRight
Expand Down
8 changes: 4 additions & 4 deletions pkg/sql/opt/norm/testdata/rules/project
Original file line number Diff line number Diff line change
Expand Up @@ -936,19 +936,19 @@ project

# No-op case because the single column in Values is not of type tuple.
norm expect-not=FoldTupleAccessIntoValues
SELECT col[1], col[2] FROM unnest(ARRAY[[1,2],[3,4]]) AS col
SELECT col[1], col[2] FROM (VALUES (ARRAY[1,2]), (ARRAY[3,4])) AS v(col)
----
project
├── columns: col:2 col:3
├── cardinality: [2 - 2]
├── values
│ ├── columns: unnest:1!null
│ ├── columns: column1:1!null
│ ├── cardinality: [2 - 2]
│ ├── (ARRAY[1,2],)
│ └── (ARRAY[3,4],)
└── projections
├── unnest:1[1] [as=col:2, outer=(1)]
└── unnest:1[2] [as=col:3, outer=(1)]
├── column1:1[1] [as=col:2, outer=(1)]
└── column1:1[2] [as=col:3, outer=(1)]

# No-op case because one of the tuple rows in Values can only be determined at
# run-time. Put dynamic tuple expression at end of list to ensure that all rows
Expand Down
22 changes: 11 additions & 11 deletions pkg/sql/opt/norm/testdata/rules/project_set
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,15 @@ values
├── key: ()
└── fd: ()-->(1)

# unnest case with array of arrays.
# unnest case with array of tuples containing arrays.
norm expect=ConvertZipArraysToValues
SELECT unnest(ARRAY[[1,2,3],[4,5]])
SELECT unnest(ARRAY[ROW(ARRAY[1,2,3]), ROW(ARRAY[4,5])])
----
values
├── columns: unnest:1!null
├── cardinality: [2 - 2]
├── (ARRAY[1,2,3],)
└── (ARRAY[4,5],)
├── ((ARRAY[1,2,3],),)
└── ((ARRAY[4,5],),)

# json_array_elements case with array of arrays.
norm expect=ConvertZipArraysToValues
Expand Down Expand Up @@ -211,10 +211,10 @@ project
└── filters (true)

# No-op case - ConvertZipArraysToValues fires the first time but not the
# second because the outer zip is over a variable of an array instead of the
# array itself.
# second because the outer zip is over an array-valued tuple field instead of
# a static array.
norm expect=ConvertZipArraysToValues
SELECT unnest(x) FROM unnest(ARRAY[[1,2,3],[4,5],[6]]) AS x
SELECT unnest((x).@1) FROM unnest(ARRAY[ROW(ARRAY[1,2,3]), ROW(ARRAY[4,5]), ROW(ARRAY[6])]) AS t(x)
----
project
├── columns: unnest:2
Expand All @@ -225,11 +225,11 @@ project
├── values
│ ├── columns: unnest:1!null
│ ├── cardinality: [3 - 3]
│ ├── (ARRAY[1,2,3],)
│ ├── (ARRAY[4,5],)
│ └── (ARRAY[6],)
│ ├── ((ARRAY[1,2,3],),)
│ ├── ((ARRAY[4,5],),)
│ └── ((ARRAY[6],),)
└── zip
└── unnest(unnest:1) [outer=(1), immutable]
└── unnest((unnest:1).@1) [outer=(1), immutable]

# No-op case - an unnest with multiple inputs is not matched.
norm expect-not=ConvertZipArraysToValues
Expand Down
26 changes: 2 additions & 24 deletions pkg/sql/opt/optbuilder/testdata/scalar
Original file line number Diff line number Diff line change
Expand Up @@ -989,15 +989,7 @@ project
build
SELECT ARRAY(VALUES (ARRAY[1]))
----
project
├── columns: array:2
├── values
│ └── ()
└── projections
└── array-flatten [as=array:2]
└── values
├── columns: column1:1
└── (ARRAY[1],)
error (0A000): unimplemented: arrays of int[] not allowed

build
SELECT ARRAY(SELECT (1, 2))
Expand Down Expand Up @@ -1279,21 +1271,7 @@ project
build
SELECT ARRAY(SELECT y FROM u ORDER BY x) FROM v
----
project
├── columns: array:10
├── scan v
│ └── columns: v.y:1 v.rowid:2!null v.crdb_internal_mvcc_timestamp:3 v.tableoid:4
└── projections
└── array-flatten col=9 [as=array:10]
└── sort
├── columns: y:9 [hidden: x:5]
├── ordering: +5
└── project
├── columns: y:9 x:5
├── scan u
│ └── columns: x:5 u.rowid:6!null u.crdb_internal_mvcc_timestamp:7 u.tableoid:8
└── projections
└── v.y:1 [as=y:9]
error (0A000): unimplemented: arrays of int[] not allowed

build-scalar
ISERROR(1/0)
Expand Down
6 changes: 3 additions & 3 deletions pkg/sql/sem/eval/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,9 +294,9 @@ func TestEvalError(t *testing.T) {
{`'1- 2:3:4 9'::interval`,
`could not parse "1- 2:3:4 9" as type interval: invalid input syntax for type interval 1- 2:3:4 9`},
{`e'\\xdedf0d36174'::BYTES`, `could not parse "\\xdedf0d36174" as type bytes: encoding/hex: odd length hex string`},
{`ARRAY[NULL, ARRAY[1, 2]]`, `multidimensional arrays must have array expressions with matching dimensions`},
{`ARRAY[ARRAY[1, 2], NULL]`, `multidimensional arrays must have array expressions with matching dimensions`},
{`ARRAY[ARRAY[1, 2], ARRAY[1]]`, `multidimensional arrays must have array expressions with matching dimensions`},
{`ARRAY[NULL, ARRAY[1, 2]]`, `unimplemented: arrays of int[] not allowed`},
{`ARRAY[ARRAY[1, 2], NULL]`, `unimplemented: arrays of int[] not allowed`},
{`ARRAY[ARRAY[1, 2], ARRAY[1]]`, `unimplemented: arrays of int[] not allowed`},
// TODO(pmattis): Check for overflow.
// {`~0 + 1`, `0`},
{`9223372036854775807::int + 1::int`, `integer out of range`},
Expand Down
20 changes: 10 additions & 10 deletions pkg/sql/sem/eval/testdata/eval/array
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ARRAY['a','b','c']
eval
ARRAY[ARRAY[1, 2], ARRAY[2, 3]]
----
ARRAY[ARRAY[1,2],ARRAY[2,3]]
unimplemented: arrays of int[] not allowed

eval
ARRAY[1, NULL]
Expand Down Expand Up @@ -60,17 +60,17 @@ NULL
eval
array_length(ARRAY[ARRAY[1, 2, 3], ARRAY[1, 2, 3]], 1)
----
2
unimplemented: arrays of int[] not allowed

eval
array_length(ARRAY[ARRAY[1, 2, 3], ARRAY[1, 2, 3]], 2)
----
3
unimplemented: arrays of int[] not allowed

eval
array_length(ARRAY[ARRAY[1, 2, 3], ARRAY[1, 2, 3]], 3)
----
NULL
unimplemented: arrays of int[] not allowed

eval
array_lower(ARRAY[1, 2, 3], 1)
Expand All @@ -95,17 +95,17 @@ NULL
eval
array_lower(ARRAY[ARRAY[1, 2, 3], ARRAY[1, 2, 3]], 1)
----
1
unimplemented: arrays of int[] not allowed

eval
array_lower(ARRAY[ARRAY[1, 2, 3], ARRAY[1, 2, 3]], 2)
----
1
unimplemented: arrays of int[] not allowed

eval
array_lower(ARRAY[ARRAY[1, 2, 3], ARRAY[1, 2, 3]], 3)
----
NULL
unimplemented: arrays of int[] not allowed

eval
array_upper(ARRAY[1, 2, 3], 1)
Expand All @@ -130,17 +130,17 @@ NULL
eval
array_upper(ARRAY[ARRAY[1, 2, 3], ARRAY[1, 2, 3]], 1)
----
2
unimplemented: arrays of int[] not allowed

eval
array_upper(ARRAY[ARRAY[1, 2, 3], ARRAY[1, 2, 3]], 2)
----
3
unimplemented: arrays of int[] not allowed

eval
array_upper(ARRAY[ARRAY[1, 2, 3], ARRAY[1, 2, 3]], 3)
----
NULL
unimplemented: arrays of int[] not allowed

# overlap, contains, contained by (&&, @>, <@)

Expand Down
2 changes: 2 additions & 0 deletions pkg/sql/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -3039,6 +3039,8 @@ func IsStringType(t *T) bool {
// the issue number should be included in the error report to inform the user.
func IsValidArrayElementType(t *T) (valid bool, issueNum int) {
switch t.Family() {
case ArrayFamily:
return false, 32552
case TSQueryFamily:
return false, 90886
case TSVectorFamily:
Expand Down
29 changes: 29 additions & 0 deletions pkg/sql/types/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,35 @@ import (
"github.com/stretchr/testify/require"
)

func TestArrayElementTypeSupport(t *testing.T) {
for _, tc := range []struct {
typ *T
issue int
}{
{String, 0},
{Int, 0},
{Unknown, 0},
{MakeTuple([]*T{StringArray}), 0},
{StringArray, 32552},
{IntArray, 32552},
{MakeArray(StringArray), 32552},
{TSQuery, 90886},
{TSVector, 90886},
{PGVector, 121432},
} {
t.Run(tc.typ.String(), func(t *testing.T) {
valid, issue := IsValidArrayElementType(tc.typ)
require.Equal(t, tc.issue == 0, valid)
require.Equal(t, tc.issue, issue)
if tc.issue == 0 {
require.NoError(t, CheckArrayElementType(tc.typ))
} else {
require.Error(t, CheckArrayElementType(tc.typ))
}
})
}
}

func TestTypes(t *testing.T) {
enCollate := "en"

Expand Down