diff --git a/e2e_test/batch/types/map.slt.part b/e2e_test/batch/types/map.slt.part index 77f311de318be..2940def273f27 100644 --- a/e2e_test/batch/types/map.slt.part +++ b/e2e_test/batch/types/map.slt.part @@ -281,7 +281,7 @@ 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 { fields: [("f1", Varchar), ("f2", Int32), ("f3", Int32)] } + 3: the underlying struct for map must have exactly two fields, got: Varchar, Int32, Int32 query error diff --git a/src/common/src/types/struct_type.rs b/src/common/src/types/struct_type.rs index 55976754f8a0e..774e96f49c241 100644 --- a/src/common/src/types/struct_type.rs +++ b/src/common/src/types/struct_type.rs @@ -32,18 +32,42 @@ pub struct StructType(Arc); impl Debug for StructType { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let alternate = f.alternate(); - - let mut d = f.debug_struct("StructType"); - d.field("fields", &self.0.fields); - if let Some(ids) = &self.0.field_ids - // TODO: This is for making `EXPLAIN` output more concise, but it hurts the readability - // for testing and debugging. Avoid using `Debug` repr in `EXPLAIN` output instead. - && alternate - { - d.field("field_ids", ids); + // `DataType` derives `Debug`, so `StructType`'s `Debug` representation frequently appears + // in `EXPLAIN` and planner test outputs. Prefer a compact single-line format for `{:?}`, + // while keeping the detailed `StructType { fields: ..., field_ids: ... }` for `{:#?}`. + if f.alternate() { + let mut d = f.debug_struct("StructType"); + d.field("fields", &self.0.fields); + if let Some(ids) = &self.0.field_ids { + d.field("field_ids", ids); + } + d.finish() + } else { + // Many internal composite types use synthetic field names like `f1`, `f2`, ... + // Treat them as unnamed to keep `EXPLAIN` output concise. + let omit_names = self.is_unnamed() + || self + .0 + .fields + .iter() + .enumerate() + .all(|(i, (name, _))| name == &format!("f{}", i + 1)); + let mut first = true; + for (name, ty) in self.iter() { + if !first { + write!(f, ", ")?; + } + first = false; + if omit_names { + // Unnamed struct comes from `ROW(...)` expressions and prints as `Struct(t1, t2, ...)`. + write!(f, "{:?}", ty)?; + } else { + // Quote the identifier when needed (e.g. reserved keywords or special chars). + write!(f, "{}:{:?}", QuoteIdent(name), ty)?; + } + } + Ok(()) } - d.finish() } } diff --git a/src/frontend/planner_test/tests/testdata/output/agg.yaml b/src/frontend/planner_test/tests/testdata/output/agg.yaml index 8f38d4cc8c5b8..1e199479716ae 100644 --- a/src/frontend/planner_test/tests/testdata/output/agg.yaml +++ b/src/frontend/planner_test/tests/testdata/output/agg.yaml @@ -2265,7 +2265,7 @@ FROM with_0 WHERE false; logical_plan: |- - LogicalProject { exprs: [null:Struct(StructType { fields: [("a", Int16), ("b", Float64), ("c", Time)] }), 995:Int32, '-168:00:00':Interval, 294:Float64] } + LogicalProject { exprs: [null:Struct(a:Int16, b:Float64, c:Time), 995:Int32, '-168:00:00':Interval, 294:Float64] } └─LogicalFilter { predicate: false:Boolean } └─LogicalShare { id: 7 } └─LogicalProject { exprs: [true:Boolean, -2147483600:Float32, -10773:Int16] } @@ -2278,6 +2278,6 @@ batch_plan: 'BatchValues { rows: [] }' stream_plan: |- StreamMaterialize { columns: [col_0, col_1, col_2, col_3, _row_id(hidden)], stream_key: [_row_id], pk_columns: [_row_id], pk_conflict: NoCheck } - └─StreamProject { exprs: [null:Struct(StructType { fields: [("a", Int16), ("b", Float64), ("c", Time)] }), 995:Int32, '-168:00:00':Interval, 294:Float64, _row_id] } + └─StreamProject { exprs: [null:Struct(a:Int16, b:Float64, c:Time), 995:Int32, '-168:00:00':Interval, 294:Float64, _row_id] } └─StreamFilter { predicate: false:Boolean } └─StreamValues { rows: [[0:Int64]] } diff --git a/src/frontend/planner_test/tests/testdata/output/array.yaml b/src/frontend/planner_test/tests/testdata/output/array.yaml index d0ab0238052ff..a1300099e4531 100644 --- a/src/frontend/planner_test/tests/testdata/output/array.yaml +++ b/src/frontend/planner_test/tests/testdata/output/array.yaml @@ -62,10 +62,10 @@ logical_plan: |- LogicalProject { exprs: [Array as $expr1] } └─LogicalValues { rows: [[]], schema: Schema { fields: [] } } - batch_plan: 'BatchValues { rows: [[ARRAY[]:List(Struct(StructType { fields: [("f1", Int32)] }))]] }' + batch_plan: 'BatchValues { rows: [[ARRAY[]:List(Struct(Int32))]] }' stream_plan: |- StreamMaterialize { columns: [array, _row_id(hidden)], stream_key: [_row_id], pk_columns: [_row_id], pk_conflict: NoCheck } - └─StreamValues { rows: [[ARRAY[]:List(Struct(StructType { fields: [("f1", Int32)] })), 0:Int64]] } + └─StreamValues { rows: [[ARRAY[]:List(Struct(Int32)), 0:Int64]] } - sql: | select array_cat(array[66], array[123]); logical_plan: |- diff --git a/src/frontend/planner_test/tests/testdata/output/expr.yaml b/src/frontend/planner_test/tests/testdata/output/expr.yaml index c5eee24321153..11e6df1a4432f 100644 --- a/src/frontend/planner_test/tests/testdata/output/expr.yaml +++ b/src/frontend/planner_test/tests/testdata/output/expr.yaml @@ -616,7 +616,7 @@ ├─BatchExchange { order: [], dist: HashShard(t.j) } │ └─BatchScan { table: t, columns: [t.k, t.j], distribution: SomeShard } └─BatchExchange { order: [], dist: HashShard(t.j) } - └─BatchProject { exprs: [t.j, JsonbPopulateRecord(null:Struct(StructType { fields: [("a", Int32), ("b", Int32)] }), t.j) as $expr1] } + └─BatchProject { exprs: [t.j, JsonbPopulateRecord(null:Struct(a:Int32, b:Int32), t.j) as $expr1] } └─BatchNestedLoopJoin { type: Inner, predicate: true, output: all } ├─BatchExchange { order: [], dist: Single } │ └─BatchHashAgg { group_key: [t.j], aggs: [] } diff --git a/src/frontend/planner_test/tests/testdata/output/row_filter.yaml b/src/frontend/planner_test/tests/testdata/output/row_filter.yaml index 3d99d10cd4d26..5cfe3aa81cad6 100644 --- a/src/frontend/planner_test/tests/testdata/output/row_filter.yaml +++ b/src/frontend/planner_test/tests/testdata/output/row_filter.yaml @@ -16,21 +16,21 @@ select * from t where (v1,v3) > (2,3); batch_plan: |- BatchExchange { order: [], dist: Single } - └─BatchFilter { predicate: (Row(t.v1, t.v3) > '(2,3)':Struct(StructType { fields: [("f1", Int32), ("f2", Int32)] })) } + └─BatchFilter { predicate: (Row(t.v1, t.v3) > '(2,3)':Struct(Int32, Int32)) } └─BatchScan { table: t, columns: [t.v1, t.v2, t.v3], scan_ranges: [t.v1 >= Int32(2)], distribution: UpstreamHashShard(t.v1, t.v2, t.v3) } - sql: | create table t(v1 int, v2 int, v3 int, primary key(v1,v2,v3)); select * from t where (v3,v2,v1) > (1,2,3); batch_plan: |- BatchExchange { order: [], dist: Single } - └─BatchFilter { predicate: (Row(t.v3, t.v2, t.v1) > '(1,2,3)':Struct(StructType { fields: [("f1", Int32), ("f2", Int32), ("f3", Int32)] })) } + └─BatchFilter { predicate: (Row(t.v3, t.v2, t.v1) > '(1,2,3)':Struct(Int32, Int32, Int32)) } └─BatchScan { table: t, columns: [t.v1, t.v2, t.v3], distribution: UpstreamHashShard(t.v1, t.v2, t.v3) } - sql: | create table t(v1 int, v2 int, v3 int, primary key(v1,v2,v3)); select * from t where (v1,v2,v1) > (1,2,3); batch_plan: |- BatchExchange { order: [], dist: Single } - └─BatchFilter { predicate: (Row(t.v1, t.v2, t.v1) > '(1,2,3)':Struct(StructType { fields: [("f1", Int32), ("f2", Int32), ("f3", Int32)] })) } + └─BatchFilter { predicate: (Row(t.v1, t.v2, t.v1) > '(1,2,3)':Struct(Int32, Int32, Int32)) } └─BatchScan { table: t, columns: [t.v1, t.v2, t.v3], scan_ranges: [(t.v1, t.v2) >= (Int32(1), Int32(2))], distribution: UpstreamHashShard(t.v1, t.v2, t.v3) } - sql: | create table t1(v1 int, v2 int, v3 int); @@ -38,5 +38,5 @@ select * from mv1 where (v1,v2,v3) > (1,3,1); batch_plan: |- BatchExchange { order: [], dist: Single } - └─BatchFilter { predicate: (Row(mv1.v1, mv1.v2, mv1.v3) > '(1,3,1)':Struct(StructType { fields: [("f1", Int32), ("f2", Int32), ("f3", Int32)] })) } + └─BatchFilter { predicate: (Row(mv1.v1, mv1.v2, mv1.v3) > '(1,3,1)':Struct(Int32, Int32, Int32)) } └─BatchScan { table: mv1, columns: [mv1.v1, mv1.v2, mv1.v3], scan_ranges: [(mv1.v1, mv1.v2) >= (Int32(1), Int32(3))], distribution: SomeShard } diff --git a/src/frontend/planner_test/tests/testdata/output/struct_query.yaml b/src/frontend/planner_test/tests/testdata/output/struct_query.yaml index d569cdafe4a0c..ff3440dc0d914 100644 --- a/src/frontend/planner_test/tests/testdata/output/struct_query.yaml +++ b/src/frontend/planner_test/tests/testdata/output/struct_query.yaml @@ -367,7 +367,7 @@ insert into s values (1,2,(1,2,(1,2,null))); logical_plan: |- LogicalInsert { table: s, mapping: [0:0, 1:1, 2:2] } - └─LogicalValues { rows: [[1:Int32, 2:Int32, Row(1:Int32, 2:Int32, Row(1:Int32, 2:Int32, null:Int32))]], schema: Schema { fields: [*VALUES*_0.column_0:Int32, *VALUES*_0.column_1:Int32, *VALUES*_0.column_2:Struct(StructType { fields: [("v1", Int32), ("v2", Int32), ("v3", Struct(StructType { fields: [("v1", Int32), ("v2", Int32), ("v3", Int32)] }))] })] } } + └─LogicalValues { rows: [[1:Int32, 2:Int32, Row(1:Int32, 2:Int32, Row(1:Int32, 2:Int32, null:Int32))]], schema: Schema { fields: [*VALUES*_0.column_0:Int32, *VALUES*_0.column_1:Int32, *VALUES*_0.column_2:Struct(v1:Int32, v2:Int32, v3:Struct(v1:Int32, v2:Int32, v3:Int32))] } } create_table_with_connector: format: plain encode: protobuf diff --git a/src/frontend/planner_test/tests/testdata/output/update.yaml b/src/frontend/planner_test/tests/testdata/output/update.yaml index e23be32f457fa..0f349b5d0197c 100644 --- a/src/frontend/planner_test/tests/testdata/output/update.yaml +++ b/src/frontend/planner_test/tests/testdata/output/update.yaml @@ -234,8 +234,8 @@ batch_plan: |- BatchExchange { order: [], dist: Single } └─BatchUpdate { table: t, exprs: [Field($4, 0:Int32), Field($4, 1:Int32), $2] } - └─BatchProject { exprs: [t.v1, t.v2, t._row_id, t._rw_timestamp, $expr10011::Struct(StructType { fields: [("v1", Int32), ("v2", Int32)] }) as $expr1] } + └─BatchProject { exprs: [t.v1, t.v2, t._row_id, t._rw_timestamp, $expr10011::Struct(v1:Int32, v2:Int32) as $expr1] } └─BatchNestedLoopJoin { type: LeftOuter, predicate: true, output: all } ├─BatchExchange { order: [], dist: Single } │ └─BatchScan { table: t, columns: [t.v1, t.v2, t._row_id, t._rw_timestamp], distribution: UpstreamHashShard(t._row_id) } - └─BatchValues { rows: [['(666.66,777)':Struct(StructType { fields: [("f1", Decimal), ("f2", Int32)] })]] } + └─BatchValues { rows: [['(666.66,777)':Struct(Decimal, Int32)]] } diff --git a/src/frontend/planner_test/tests/testdata/output/vector_search.yaml b/src/frontend/planner_test/tests/testdata/output/vector_search.yaml index ca62b9336b9fa..196e3b2d2539e 100644 --- a/src/frontend/planner_test/tests/testdata/output/vector_search.yaml +++ b/src/frontend/planner_test/tests/testdata/output/vector_search.yaml @@ -383,7 +383,7 @@ LogicalProject { exprs: [events.event_id, $expr3, events.time] } └─LogicalApply { type: LeftOuter, on: true, correlated_id: 1, max_one_row: true } ├─LogicalScan { table: events, columns: [events.event_id, events.time, events.embedding, events._rw_timestamp] } - └─LogicalProject { exprs: [Coalesce(array_agg($expr1 order_by($expr2 ASC)), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Varchar)] }))) as $expr3] } + └─LogicalProject { exprs: [Coalesce(array_agg($expr1 order_by($expr2 ASC)), ARRAY[]:List(Struct(Int32, Varchar))) as $expr3] } └─LogicalAgg { aggs: [array_agg($expr1 order_by($expr2 ASC))] } └─LogicalTopN { order: [$expr2 ASC], limit: 3, offset: 0 } └─LogicalProject { exprs: [Row(items.id, items.name) as $expr1, CosineDistance(CorrelatedInputRef { index: 2, correlated_id: 1 }, items.embedding) as $expr2] } @@ -391,7 +391,7 @@ optimized_logical_plan_for_batch: |- LogicalJoin { type: LeftOuter, on: IsNotDistinctFrom(events.embedding, events.embedding), output: [events.event_id, $expr3, events.time] } ├─LogicalScan { table: events, columns: [events.event_id, events.time, events.embedding] } - └─LogicalProject { exprs: [events.embedding, Coalesce(array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Varchar)] }))) as $expr3] } + └─LogicalProject { exprs: [events.embedding, Coalesce(array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(Int32, Varchar))) as $expr3] } └─LogicalAgg { group_key: [events.embedding], aggs: [array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32))] } └─LogicalJoin { type: LeftOuter, on: IsNotDistinctFrom(events.embedding, events.embedding), output: [events.embedding, $expr1, $expr2, 1:Int32] } ├─LogicalAgg { group_key: [events.embedding], aggs: [] } @@ -408,7 +408,7 @@ └─BatchHashJoin { type: LeftOuter, predicate: events.embedding IS NOT DISTINCT FROM events.embedding, output: [events.event_id, $expr3, events.time] } ├─BatchExchange { order: [], dist: HashShard(events.embedding) } │ └─BatchScan { table: events, columns: [events.event_id, events.time, events.embedding], distribution: UpstreamHashShard(events.event_id) } - └─BatchProject { exprs: [events.embedding, Coalesce(array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Varchar)] }))) as $expr3] } + └─BatchProject { exprs: [events.embedding, Coalesce(array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(Int32, Varchar))) as $expr3] } └─BatchHashAgg { group_key: [events.embedding], aggs: [array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32))] } └─BatchHashJoin { type: LeftOuter, predicate: events.embedding IS NOT DISTINCT FROM events.embedding, output: [events.embedding, $expr1, $expr2, 1:Int32] } ├─BatchHashAgg { group_key: [events.embedding], aggs: [] } @@ -441,7 +441,7 @@ LogicalProject { exprs: [events.event_id, events.time, events.embedding, $expr3] } └─LogicalApply { type: LeftOuter, on: true, correlated_id: 1, max_one_row: true } ├─LogicalScan { table: events, columns: [events.event_id, events.time, events.embedding, events._rw_timestamp] } - └─LogicalProject { exprs: [Coalesce(array_agg($expr1 order_by($expr2 ASC)), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Varchar)] }))) as $expr3] } + └─LogicalProject { exprs: [Coalesce(array_agg($expr1 order_by($expr2 ASC)), ARRAY[]:List(Struct(Int32, Varchar))) as $expr3] } └─LogicalAgg { aggs: [array_agg($expr1 order_by($expr2 ASC))] } └─LogicalTopN { order: [$expr2 ASC], limit: 3, offset: 0 } └─LogicalProject { exprs: [Row(items.id, items.name) as $expr1, CosineDistance(items.embedding, CorrelatedInputRef { index: 2, correlated_id: 1 }) as $expr2] } @@ -449,7 +449,7 @@ optimized_logical_plan_for_batch: |- LogicalJoin { type: LeftOuter, on: IsNotDistinctFrom(events.embedding, events.embedding), output: [events.event_id, events.time, events.embedding, $expr3] } ├─LogicalScan { table: events, columns: [events.event_id, events.time, events.embedding] } - └─LogicalProject { exprs: [events.embedding, Coalesce(array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Varchar)] }))) as $expr3] } + └─LogicalProject { exprs: [events.embedding, Coalesce(array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(Int32, Varchar))) as $expr3] } └─LogicalAgg { group_key: [events.embedding], aggs: [array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32))] } └─LogicalJoin { type: LeftOuter, on: IsNotDistinctFrom(events.embedding, events.embedding), output: [events.embedding, $expr1, $expr2, 1:Int32] } ├─LogicalAgg { group_key: [events.embedding], aggs: [] } @@ -466,7 +466,7 @@ └─BatchHashJoin { type: LeftOuter, predicate: events.embedding IS NOT DISTINCT FROM events.embedding, output: [events.event_id, events.time, events.embedding, $expr3] } ├─BatchExchange { order: [], dist: HashShard(events.embedding) } │ └─BatchScan { table: events, columns: [events.event_id, events.time, events.embedding], distribution: UpstreamHashShard(events.event_id) } - └─BatchProject { exprs: [events.embedding, Coalesce(array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Varchar)] }))) as $expr3] } + └─BatchProject { exprs: [events.embedding, Coalesce(array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(Int32, Varchar))) as $expr3] } └─BatchHashAgg { group_key: [events.embedding], aggs: [array_agg($expr1 order_by($expr2 ASC)) filter(IsNotNull(1:Int32))] } └─BatchHashJoin { type: LeftOuter, predicate: events.embedding IS NOT DISTINCT FROM events.embedding, output: [events.embedding, $expr1, $expr2, 1:Int32] } ├─BatchHashAgg { group_key: [events.embedding], aggs: [] } @@ -498,7 +498,7 @@ LogicalProject { exprs: [events.event_id, $expr3, events.time] } └─LogicalApply { type: LeftOuter, on: true, correlated_id: 1, max_one_row: true } ├─LogicalScan { table: events, columns: [events.event_id, events.time, events.embedding, events._rw_timestamp] } - └─LogicalProject { exprs: [Coalesce(array_agg($expr2), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Float64), ("f3", Varchar)] }))) as $expr3] } + └─LogicalProject { exprs: [Coalesce(array_agg($expr2), ARRAY[]:List(Struct(Int32, Float64, Varchar))) as $expr3] } └─LogicalAgg { aggs: [array_agg($expr2)] } └─LogicalProject { exprs: [Row(items.id, $expr1, items.name) as $expr2] } └─LogicalTopN { order: [$expr1 ASC], limit: 3, offset: 0 } @@ -507,7 +507,7 @@ optimized_logical_plan_for_batch: |- LogicalJoin { type: LeftOuter, on: IsNotDistinctFrom(events.embedding, events.embedding), output: [events.event_id, $expr3, events.time] } ├─LogicalScan { table: events, columns: [events.event_id, events.time, events.embedding] } - └─LogicalProject { exprs: [events.embedding, Coalesce(array_agg($expr2) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Float64), ("f3", Varchar)] }))) as $expr3] } + └─LogicalProject { exprs: [events.embedding, Coalesce(array_agg($expr2) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(Int32, Float64, Varchar))) as $expr3] } └─LogicalAgg { group_key: [events.embedding], aggs: [array_agg($expr2) filter(IsNotNull(1:Int32))] } └─LogicalJoin { type: LeftOuter, on: IsNotDistinctFrom(events.embedding, events.embedding), output: [events.embedding, $expr2, 1:Int32] } ├─LogicalAgg { group_key: [events.embedding], aggs: [] } @@ -524,7 +524,7 @@ └─BatchHashJoin { type: LeftOuter, predicate: events.embedding IS NOT DISTINCT FROM events.embedding, output: [events.event_id, $expr3, events.time] } ├─BatchExchange { order: [], dist: HashShard(events.embedding) } │ └─BatchScan { table: events, columns: [events.event_id, events.time, events.embedding], distribution: UpstreamHashShard(events.event_id) } - └─BatchProject { exprs: [events.embedding, Coalesce(array_agg($expr2) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Float64), ("f3", Varchar)] }))) as $expr3] } + └─BatchProject { exprs: [events.embedding, Coalesce(array_agg($expr2) filter(IsNotNull(1:Int32)), ARRAY[]:List(Struct(Int32, Float64, Varchar))) as $expr3] } └─BatchHashAgg { group_key: [events.embedding], aggs: [array_agg($expr2) filter(IsNotNull(1:Int32))] } └─BatchHashJoin { type: LeftOuter, predicate: events.embedding IS NOT DISTINCT FROM events.embedding, output: [events.embedding, $expr2, 1:Int32] } ├─BatchHashAgg { group_key: [events.embedding], aggs: [] } @@ -561,7 +561,7 @@ LogicalProject { exprs: [events.event_id, $expr3, events.time] } └─LogicalApply { type: LeftOuter, on: true, correlated_id: 1, max_one_row: true } ├─LogicalScan { table: events, columns: [events.event_id, events.time, events.embedding, events._rw_timestamp] } - └─LogicalProject { exprs: [Coalesce(array_agg($expr2), ARRAY[]:List(Struct(StructType { fields: [("f1", Varchar)] }))) as $expr3] } + └─LogicalProject { exprs: [Coalesce(array_agg($expr2), ARRAY[]:List(Struct(Varchar))) as $expr3] } └─LogicalAgg { aggs: [array_agg($expr2)] } └─LogicalProject { exprs: [Row(items.name) as $expr2] } └─LogicalProject { exprs: [items.name] } @@ -593,7 +593,7 @@ LogicalProject { exprs: [events.event_id, $expr3, events.time] } └─LogicalApply { type: LeftOuter, on: true, correlated_id: 1, max_one_row: true } ├─LogicalScan { table: events, columns: [events.event_id, events.time, events.embedding, events._rw_timestamp] } - └─LogicalProject { exprs: [Coalesce(array_agg($expr2), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Varchar), ("f3", Float64)] }))) as $expr3] } + └─LogicalProject { exprs: [Coalesce(array_agg($expr2), ARRAY[]:List(Struct(Int32, Varchar, Float64))) as $expr3] } └─LogicalAgg { aggs: [array_agg($expr2)] } └─LogicalProject { exprs: [Row(items.id, items.name, $expr1) as $expr2] } └─LogicalTopN { order: [$expr1 ASC], limit: 3, offset: 0 } @@ -624,7 +624,7 @@ LogicalProject { exprs: [events.event_id, $expr3, events.time] } └─LogicalApply { type: LeftOuter, on: true, correlated_id: 1, max_one_row: true } ├─LogicalScan { table: events, columns: [events.event_id, events.time, events.embedding, events._rw_timestamp] } - └─LogicalProject { exprs: [Coalesce(array_agg($expr2), ARRAY[]:List(Struct(StructType { fields: [("f1", Varchar)] }))) as $expr3] } + └─LogicalProject { exprs: [Coalesce(array_agg($expr2), ARRAY[]:List(Struct(Varchar))) as $expr3] } └─LogicalAgg { aggs: [array_agg($expr2)] } └─LogicalProject { exprs: [Row(items.name) as $expr2] } └─LogicalProject { exprs: [items.name] } @@ -656,7 +656,7 @@ LogicalProject { exprs: [events.event_id, $expr3, events.time] } └─LogicalApply { type: LeftOuter, on: true, correlated_id: 1, max_one_row: true } ├─LogicalScan { table: events, columns: [events.event_id, events.time, events.embedding, events._rw_timestamp] } - └─LogicalProject { exprs: [Coalesce(array_agg($expr2), ARRAY[]:List(Struct(StructType { fields: [("f1", Int32), ("f2", Varchar), ("f3", Float64)] }))) as $expr3] } + └─LogicalProject { exprs: [Coalesce(array_agg($expr2), ARRAY[]:List(Struct(Int32, Varchar, Float64))) as $expr3] } └─LogicalAgg { aggs: [array_agg($expr2)] } └─LogicalProject { exprs: [Row(items.id, items.name, $expr1) as $expr2] } └─LogicalTopN { order: [$expr1 ASC], limit: 3, offset: 0 }