Skip to content

Commit

Permalink
feat: support more map functions (#18073)
Browse files Browse the repository at this point in the history
  • Loading branch information
xxchan authored Aug 19, 2024
1 parent 4ecacbc commit 24105cd
Show file tree
Hide file tree
Showing 19 changed files with 482 additions and 76 deletions.
139 changes: 116 additions & 23 deletions e2e_test/batch/types/map.slt.part
Original file line number Diff line number Diff line change
Expand Up @@ -8,66 +8,66 @@ create table t (m map (float, float));
db error: ERROR: Failed to run the query

Caused by:
invalid map key type: double precision
Bind error: invalid map key type: double precision


query error
select map_from_entries(array[1.0,2.0,3.0], array[1,2,3]);
select map_from_key_values(array[1.0,2.0,3.0], array[1,2,3]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Failed to bind expression: map_from_entries(ARRAY[1.0, 2.0, 3.0], ARRAY[1, 2, 3])
1: Failed to bind expression: map_from_key_values(ARRAY[1.0, 2.0, 3.0], ARRAY[1, 2, 3])
2: Expr error
3: invalid map key type: numeric


query error
select map_from_entries(array[1,1,3], array[1,2,3]);
select map_from_key_values(array[1,1,3], array[1,2,3]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Expr error
2: error while evaluating expression `map_from_entries('{1,1,3}', '{1,2,3}')`
2: error while evaluating expression `map_from_key_values('{1,1,3}', '{1,2,3}')`
3: map keys must be unique


query ?
select map_from_entries(array[1,2,3], array[1,null,3]);
select map_from_key_values(array[1,2,3], array[1,null,3]);
----
{1:1,2:NULL,3:3}


query error
select map_from_entries(array[1,null,3], array[1,2,3]);
select map_from_key_values(array[1,null,3], array[1,2,3]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Expr error
2: error while evaluating expression `map_from_entries('{1,NULL,3}', '{1,2,3}')`
2: error while evaluating expression `map_from_key_values('{1,NULL,3}', '{1,2,3}')`
3: map keys must not be NULL


query error
select map_from_entries(array[1,3], array[1,2,3]);
select map_from_key_values(array[1,3], array[1,2,3]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Expr error
2: error while evaluating expression `map_from_entries('{1,3}', '{1,2,3}')`
2: error while evaluating expression `map_from_key_values('{1,3}', '{1,2,3}')`
3: map keys and values have different length


query error
select map_from_entries(array[1,2], array[1,2]) = map_from_entries(array[2,1], array[2,1]);
select map_from_key_values(array[1,2], array[1,2]) = map_from_key_values(array[2,1], array[2,1]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Failed to bind expression: map_from_entries(ARRAY[1, 2], ARRAY[1, 2]) = map_from_entries(ARRAY[2, 1], ARRAY[2, 1])
1: Failed to bind expression: map_from_key_values(ARRAY[1, 2], ARRAY[1, 2]) = map_from_key_values(ARRAY[2, 1], ARRAY[2, 1])
2: function equal(map(integer,integer), map(integer,integer)) does not exist


Expand All @@ -83,32 +83,32 @@ create table t (

statement ok
insert into t values (
map_from_entries(array['a','b','c'], array[1.0,2.0,3.0]::float[]),
map_from_entries(array[1,2,3], array[true,false,true]),
map_from_entries(array['a','b'],
map_from_key_values(array['a','b','c'], array[1.0,2.0,3.0]::float[]),
map_from_key_values(array[1,2,3], array[true,false,true]),
map_from_key_values(array['a','b'],
array[
map_from_entries(array['a1'], array['a2']),
map_from_entries(array['b1'], array['b2'])
map_from_key_values(array['a1'], array['a2']),
map_from_key_values(array['b1'], array['b2'])
]
),
array[
map_from_entries(array['a','b','c'], array[1,2,3]),
map_from_entries(array['d','e','f'], array[4,5,6])
map_from_key_values(array['a','b','c'], array[1,2,3]),
map_from_key_values(array['d','e','f'], array[4,5,6])
],
row(
map_from_entries(array['a','b','c'], array[row(1),row(2),row(3)]::struct<x int>[])
map_from_key_values(array['a','b','c'], array[row(1),row(2),row(3)]::struct<x int>[])
)
);

# cast(map(character varying,integer)) -> map(character varying,double precision)
query ?
select map_from_entries(array['a','b','c'], array[1,2,3])::map(varchar,float);
select map_from_key_values(array['a','b','c'], array[1,2,3])::map(varchar,float);
----
{a:1,b:2,c:3}


statement ok
insert into t(m1) values (map_from_entries(array['a','b','c'], array[1,2,3]));
insert into t(m1) values (map_from_key_values(array['a','b','c'], array[1,2,3]));

query ????? rowsort
select * from t;
Expand Down Expand Up @@ -144,7 +144,7 @@ db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Expr error
2: error while evaluating expression `map_from_entries('{a,a}', '{1,2}')`
2: error while evaluating expression `map_from_key_values('{a,a}', '{1,2}')`
3: map keys must be unique


Expand All @@ -165,3 +165,96 @@ select
MAP{1:'a',2:'b'}::MAP(VARCHAR,VARCHAR)
----
{} {1:a,2:b}

query error
select map_from_entries(array[]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Failed to bind expression: map_from_entries(ARRAY[])
2: Bind error: cannot determine type of empty array
HINT: Explicitly cast to the desired type, for example ARRAY[]::integer[].


query error
select map_from_entries(array[]::int[]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Failed to bind expression: map_from_entries(CAST(ARRAY[] AS INT[]))
2: Expr error
3: invalid map entries type, expected struct, got: integer


query error
select map_from_entries(array[]::struct<key float, value int>[]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Failed to bind expression: map_from_entries(CAST(ARRAY[] AS STRUCT<key FLOAT, value INT>[]))
2: Expr error
3: invalid map key type: double precision


query ?
select map_from_entries(array[]::struct<key int, value int>[]);
----
{}


query ?
select map_from_entries(array[row('a',1), row('b',2), row('c',3)]);
----
{a:1,b:2,c:3}


query error
select map_from_entries(array[row('a',1), row('a',2), row('c',3)]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Expr error
2: error while evaluating expression `map_from_entries('{"(a,1)","(a,2)","(c,3)"}')`
3: map keys must be unique


query error
select map_from_entries(array[row('a',1,2)]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Failed to bind expression: map_from_entries(ARRAY[ROW('a', 1, 2)])
2: Expr error
3: the underlying struct for map must have exactly two fields, got: StructType { field_names: [], field_types: [Varchar, Int32, Int32] }


query error
select map_from_entries(array[row(1.0,1)]);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Failed to bind expression: map_from_entries(ARRAY[ROW(1.0, 1)])
2: Expr error
3: invalid map key type: numeric


query error
select map_from_entries(null);
----
db error: ERROR: Failed to run the query

Caused by these errors (recent errors listed first):
1: Failed to bind expression: map_from_entries(NULL)
2: Bind error: Cannot implicitly cast 'null:Varchar' to polymorphic type AnyArray


query ?
select map_from_entries(null::struct<key int, value int>[]);
----
NULL
9 changes: 9 additions & 0 deletions proto/expr.proto
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,15 @@ message ExprNode {
// Map functions
MAP_FROM_ENTRIES = 700;
MAP_ACCESS = 701;
MAP_KEYS = 702;
MAP_VALUES = 703;
MAP_ENTRIES = 704;
MAP_FROM_KEY_VALUES = 705;
MAP_LENGTH = 706;
MAP_CONTAINS = 707;
MAP_CAT = 708;
MAP_INSERT = 709;
MAP_DELETE = 710;

// Non-pure functions below (> 1000)
// ------------------------
Expand Down
4 changes: 2 additions & 2 deletions src/common/src/array/list_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,11 +372,11 @@ impl ListValue {

/// Creates a new `ListValue` from an iterator of `Datum`.
pub fn from_datum_iter<T: ToDatumRef>(
datatype: &DataType,
elem_datatype: &DataType,
iter: impl IntoIterator<Item = T>,
) -> Self {
let iter = iter.into_iter();
let mut builder = datatype.create_array_builder(iter.size_hint().0);
let mut builder = elem_datatype.create_array_builder(iter.size_hint().0);
for datum in iter {
builder.append(datum);
}
Expand Down
Loading

0 comments on commit 24105cd

Please sign in to comment.